+++ /dev/null
-<!doctype linuxdoc system>
-
-<article>
-
-<!-- Title information -->
-
-<title>GTK+ FAQ
-
-<!-- NOTE: Use only one author tag, otherwise sgml2txt barfs - TRG -->
-<author>Tony Gale, Shawn T. Amundson, Emmanuel Deloget, Nathan Froyd
-
-<date>March 9th 2000
-
-<abstract> This document is intended to answer questions that are likely to be
-frequently asked by programmers using GTK+ or people who are just looking at
-using GTK+.
-</abstract>
-
-<!-- Table of contents -->
-<toc>
-
-<!-- Begin the document -->
-
-<!-- ***************************************************************** -->
-<sect>General Information
-
-<!-- ----------------------------------------------------------------- -->
-<sect1>Before anything else: the greetings
-<p>
-The FAQ authors want to thank:
-<itemize>
-<item>Havoc Pennington
-<item>Erik Mouw
-<item>Owen Taylor
-<item>Tim Janik
-<item>Thomas Mailund Jensen
-<item>Joe Pfeiffer
-<item>Andy Kahn
-<item>Federico Mena Quintero
-<item>Damon Chaplin
-<item>and all the members of the GTK+ lists
-</itemize>
-If we forgot you, please email us !
-Thanks again (I know, it's really short :)
-
-<!-- ----------------------------------------------------------------- -->
-<sect1>Authors
-<p>
-The original authors of GTK+ were:
-
-<itemize>
-<item>Peter Mattis
-<item>Spencer Kimball
-<item>Josh MacDonald
-</itemize>
-
-Since then, much has been added by others. Please see the AUTHORS
-file in the distribution for the GTK+ Team.
-
-<!-- ----------------------------------------------------------------- -->
-<sect1>What is GTK+?
-<p>
-GTK+ is a small and efficient widget set designed with the general
-look and feel of Motif. In reality, it looks much better than Motif.
-It contains common widgets and some more complex widgets such as a
-file selection, and color selection widgets.
-
-GTK+ provides some unique features. (At least, I know of no other
-widget library which provides them). For example, a button does not
-contain a label, it contains a child widget, which in most instances
-will be a label. However, the child widget can also be a pixmap,
-image or any combination possible the programmer desires. This
-flexibility is adhered to throughout the library.
-
-<!-- ----------------------------------------------------------------- -->
-<sect1>What is the + in GTK+?
-<P>
-Peter Mattis informed the gtk mailing list that:
-<quote>
-"I originally wrote gtk which included the three libraries, libglib,
-libgdk and libgtk. It featured a flat widget hierarchy. That is, you
-couldn't derive a new widget from an existing one. And it contained
-a more standard callback mechanism instead of the signal mechanism now
-present in gtk+. The + was added to distinguish between the original
-version of gtk and the new version. You can think of it as being an
-enhancement to the original gtk that adds object oriented features."
-</quote>
-
-<!-- ----------------------------------------------------------------- -->
-<sect1>Does the G in GTK+, GDK and GLib stand for?
-<p>
-GTK+ == Gimp Toolkit
-
-GDK == GTK+ Drawing Kit
-
-GLib == G Libray
-
-<!-- ----------------------------------------------------------------- -->
-<sect1>Where is the documentation for GTK+?
-<p>
-In the GTK+ distribution's doc/ directory you will find the
-reference material for both GTK and GDK, this FAQ and the
-GTK Tutorial.
-
-In addition, you can find links to HTML versions of these documents
-by going to <htmlurl url="http://www.gtk.org/"
-name="http://www.gtk.org/">. A packaged version of the GTK Tutorial,
-with SGML, HTML, Postscript, DVI and text versions can be found in
-<htmlurl url="ftp://ftp.gtk.org/pub/gtk/tutorial"
-name="ftp://ftp.gtk.org/pub/gtk/tutorial">
-
-There are now a couple of books available that deal with programming
-GTK+, GDK and GNOME:
-<itemize>
-<item> Eric Harlows book entitled "Developing Linux Applications with
-GTK+ and GDK". The ISBN is 0-7357-0021-4
-<P>
-The example code from Eric's book is available on-line at
-<htmlurl url="http://www.bcpl.net/~eharlow/book"
-name="http://www.bcpl.net/~eharlow/book">
-
-<item> Havoc Pennington has released a book called "GTK+/GNOME
-Application Development". The ISBN is 0-7357-0078-8
-<P>
-The free version of the book lives here:
-<htmlurl url="http://developer.gnome.org/doc/GGAD/"
-name="http://developer.gnome.org/doc/GGAD/">
-<P>
-And Havoc maintains information about it and errata here:
-<htmlurl url="http://pobox.com/~hp/gnome-app-devel.html"
-name="http://pobox.com/~hp/gnome-app-devel.html">
-</itemize>
-
-<!-- ----------------------------------------------------------------- -->
-<sect1>Is there a mailing list (or mailing list archive) for GTK+?
-<p>
-Information on mailing lists relating to GTK+ can be found at:
-
-<htmlurl url="http://www.gtk.org/mailinglists.html"
-name="http://www.gtk.org/mailinglists.html">
-
-<!-- ----------------------------------------------------------------- -->
-<sect1>How to get help with GTK+
-<p>
-First, make sure your question isn't answered in the documentation,
-this FAQ or the tutorial. Done that? You're sure you've done that,
-right? In that case, the best place to post questions is to the GTK+
-mailing list.
-
-<!-- ----------------------------------------------------------------- -->
-<sect1>How to report bugs in GTK+
-<p>
-Bugs should be reported to the GNOME bug tracking
-system (<htmlurl url="http://bugs.gnome.org"
-name="http://bugs.gnome.org">). To report a problem about GTK+, send
-mail to submit@bugs.gnome.org.
-
-The subject of the mail should describe your problem. In the body of
-the mail, you should first include a "pseudo-header" that gives the
-package and version number. This should be separated by a blank line
-from the actual headers.
-
-<verb>
- Package: gtk+
- Version: 1.2.0
-</verb>
-
-Substitute 1.2.0 with the version of GTK+ that you have installed.
-
-Then describe the bug. Include:
-
-<itemize>
-<item> Information about your system. For instance:
- <itemize>
- <item> What operating system and version
- <item> What version of X
- <item> For Linux, what version of the C library
- </itemize>
- And anything else you think is relevant.
-
-<item> How to reproduce the bug.
-
- If you can reproduce it with the testgtk program that is built in
- the gtk/ subdirectory, that will be most convenient. Otherwise,
- please include a short test program that exhibits the behavior. As
- a last resort, you can also provide a pointer to a larger piece of
- software that can be downloaded.
-
- (Bugs that can be reproduced within the GIMP are almost as good as
- bugs that can be reproduced in testgtk. If you are reporting a bug
- found with the GIMP, please include the version number of the GIMP
- you are using)
-
-<item> If the bug was a crash, the exact text that was printed out
- when the crash occured.
-
-<item> Further information such as stack traces may be useful, but are
- not necessary. If you do send a stack trace, and the error is an X
- error, it will be more useful if the stacktrace is produced running
- the test program with the <tt/--sync/ command line option.
-</itemize>
-
-<!-- ----------------------------------------------------------------- -->
-<sect1>Is there a Windows version of GTK+?
-<p>
-There is an on going port of GTK+ to the Windows platform which is
-making impressive progress.
-
-See <htmlurl url="http://www.iki.fi/tml/gimp/win32"
-name="http://www.iki.fi/tml/gimp/win32"> for more information.
-
-<!-- ----------------------------------------------------------------- -->
-<sect1>What applications have been written with GTK+?
-<p>
-A list of some GTK+ based application can be found on the GTK+ web
-server at <htmlurl url="http://www.gtk.org/apps/"
-name="http://www.gtk.org/apps/"> and contains more than 350
-applications.
-
-Failing that, look for a project to work on for the GNOME project,
-<htmlurl url="http://www.gnome.org/" name="http://www.gnome.org/">
-Write a game. Write something that is useful.
-
-Some of these are:
-<itemize>
-<item>GIMP (<htmlurl url="http://www.gimp.org/"
- name="http://www.gimp.org/">),
- an image manipulation program
-<item>AbiWord (<htmlurl url="http://www.abisource.com/"
- name="http://www.abisource.com/">),
- a professional word processor
-<item>GUBI (<htmlurl url="http://www.SoftHome.net/pub/users/timj/gubi/index.htm"
- name="http://www.SoftHome.net/pub/users/timj/gubi/index.htm">),
- a user interface builder
-<item>Gzilla (<htmlurl url="http://www.levien.com/gzilla/"
- name="http://www.levien.com/gzilla/">),
- a web browser
-<item>SANE (<htmlurl url="http://www.azstarnet.com/~axplinux/sane/"
- name="http://www.azstarnet.com/~axplinux/sane/"> ),
- a universal scanner interface
-<item>XQF (<htmlurl url="http://www.botik.ru/~roma/quake/"
- name="http://www.botik.ru/~roma/quake/">),
- a QuakeWorld/Quake2 server browser and launcher
-<item>ElectricEyes (<htmlurl url="http://www.labs.redhat.com/ee.shtml"
- name="http://www.labs.redhat.com/ee.shtml">),
- an image viewer that aims to be a free replacement for xv
-<item>GPK - the General Proxy Kit (<htmlurl url="http://www.humanfactor.com/gpk/"
- name="http://www.humanfactor.com/gpk/">),
- an add-on library to permit thread-safe access to GTK+
-<item>GCK - the General Convenience Kit (<htmlurl url="http://www.ii.uib.no/~tomb/gck.html"
- name="http://www.ii.uib.no/~tomb/gck.html">),
- miscellaneous functions intended to ease color handling, UI construction,
- vector operations, and math functions
-<item>GDK Imlib (<htmlurl url="http://www.labs.redhat.com/imlib/"
- name="http://www.labs.redhat.com/imlib/">),
- a fast image loading and manipulation library for GDK
-<item>Glade (<htmlurl url="http://glade.pn.org/"
- name="http://glade.pn.org/">),
- a GTK+ based RAD tool which produces GTK+ applications
-</itemize>
-<p>
-In addition to the above, the GNOME project (<htmlurl
-url="http://www.gnome.org" name="http://www.gnome.org">) is using GTK+
-to build a free desktop for Linux. Many more programs can be found
-there.
-
-<!-- ----------------------------------------------------------------- -->
-<sect1>I'm looking for an application to write in GTK+. How about an IRC client?
-<p>
-
-Ask on gtk-list for suggestions. There are at least three IRC clients
-already under development (probably more in fact. The server at
-<htmlurl url="http://www.forcix.cx/irc-clients.html"
-name="http://www.forcix.cx/irc-clients.html"> list a bunch of them).
-
-<itemize>
-<item>X-Chat.
-<item>girc. (Included with GNOME)
-<item>gsirc. (In the gnome CVS tree)
-</itemize>
-
-<!-- ***************************************************************** -->
-<sect>How to find, configure, install, and troubleshoot GTK+
-<!-- ***************************************************************** -->
-
-<!-- ----------------------------------------------------------------- -->
-<sect1>What do I need to run GTK+?
-<p>
-To compile GTK+, all you need is a C compiler (gcc) and the X Window System
-and associated libraries on your system.
-
-<!-- ----------------------------------------------------------------- -->
-<sect1>Where can I get GTK+?
-<p>
-The canonical site is:
-<verb>
-ftp://ftp.gtk.org/pub/gtk
-</verb>
-This site tends to get busy around the time of a new GTK+ release
-so try and use one of the mirror sites that are listed in
-<htmlurl url="ftp://ftp.gtk.org/etc/mirrors"
-name="ftp://ftp.gtk.org/etc/mirrors">
-
-Here's a few mirror sites to get you started:
-<itemize>
-<item>Africa - ftp://ftp.is.co.za/applications/gimp/
-<item>Australia - ftp://ftp.au.gimp.org/pub/gimp/
-<item>Finland - ftp://ftp.funet.fi/pub/sci/graphics/packages/gimp
-<item>Germany - ftp://infosoc.uni-koeln.de/pub/ftp.gimp.org/
-<item>Japan - ftp://SunSITE.sut.ac.jp/pub/archives/packages/gimp/
-<item>UK - ftp://ftp.flirble.org/pub/X/gimp/
-<item>US - ftp://ftp.insync.net/pub/mirrors/ftp.gimp.org/
-</itemize>
-
-<!-- ----------------------------------------------------------------- -->
-<sect1>How do I configure/compile GTK+?
-<p>
-Generally, all you will need to do is issue the commands:
-<verb>
-./configure
-make
-</verb>
-in the gtk+-version/ directory.
-
-<!-- ----------------------------------------------------------------- -->
-<sect1>When compiling GTK+ I get an error like:
-<tt/make: file `Makefile' line 456: Syntax error/
-<p>
-Make sure that you are using GNU make (use <tt/make -v/ to
-check). There are many weird and wonderful versions of make out there,
-and not all of them handle the automatically generated Makefiles.
-
-<!-- ----------------------------------------------------------------- -->
-
-<sect1>I've compiled and installed GTK+, but I can't get any programs to link with it!
-<p>
-This problem is most often encountered when the GTK+ libraries can't
-be found or are the wrong version. Generally, the compiler will
-complain about an 'unresolved symbol'. There are two things you need
-to check:
-<itemize>
-<item>Make sure that the libraries can be found. You want to edit
-/etc/ld.so.conf to include the directories which contain the GTK
-libraries, so it looks something like:
-<verb>
-/usr/X11R6/lib
-/usr/local/lib
-</verb>
-Then you need to run /sbin/ldconfig as root. You can find what directory
-GTK is in using
-<verb>
-gtk-config --libs
-</verb>
-
-If your system doesn't use ld.so to find libraries (such as Solaris), then
-you will have to use the LD_LIBRARY_PATH environment variable (or compile
-the path into your program, which I'm not going to cover here). So, with a
-Bourne type shell you can do (if your GTK libraries are in /usr/local/lib):
-<verb>
-export LD_LIBRARY_PATH=/usr/local/lib
-</verb>
-and in a csh, you can do:
-<verb>
-setenv LD_LIBRARY_PATH /usr/local/lib
-</verb>
-
-<item>Make sure the linker is finding the correct set of libraries. If you
-have a Linux distribution that installs GTK+ (e.g. RedHat 5.0) then this
-older version may be used. Now (assuming you have a RedHat
-system), issue the command
-<verb>
-rpm -e gtk gtk-devel
-</verb>
-You may also want to remove the packages that depend on gtk (rpm will
-tell you which ones they are). If you don't have a RedHat Linux
-system, check to make sure that neither <verb>/usr/lib</verb> or
-<verb>/usr/local/lib</verb> contain any of the libraries libgtk,
-libgdk, libglib, or libgck. If they do exist, remove them (and any
-gtk include files, such as /usr/include/gtk and /usr/include/gdk) and
-reinstall gtk+. </itemize>
-
-<!-- ----------------------------------------------------------------- -->
-<sect1>When compiling programs with GTK+, I get compiler error messages about not being able to find <tt/"glibconfig.h"/.
-<p>
-The header file "glibconfig.h" was moved to the directory
-$exec_prefix/lib/glib/include/. $exec_prefix is the
-directory that was specified by giving the --exec-prefix
-flags to ./configure when compiling GTK+. It defaults to
-$prefix, (specified with --prefix), which in turn defaults
-to /usr/local/.
-
-This was done because "glibconfig.h" includes architecture
-dependent information, and the rest of the include files
-are put in $prefix/include, which can be shared between different
-architectures.
-
-GTK+ includes a shell script, <tt/gtk-config/, that
-makes it easy to find out the correct include paths.
-The GTK+ tutorial includes an example of using <tt/gtk-config/
-for simple compilation from the command line. For information
-about more complicated configuration, see the file
-docs/gtk-config.txt in the GTK+ distribution.
-
-If you are trying to compile an old program, you may
-be able to work around the problem by configuring it
-with a command line like:
-
-<tscreen><verb>
-CPPFLAGS="-I/usr/local/include/glib/include" ./configure
-</verb></tscreen>
-
-for Bourne-compatible shells like bash, or for csh variants:
-
-<tscreen><verb>
-setenv CPPFLAGS "-I/usr/local/include/glib/include"
-./configure
-</verb></tscreen>
-
-(Substitute the appropriate value of $exec_prefix for /usr/local.)
-
-<!-- ----------------------------------------------------------------- -->
-<sect1>When installing a GTK+ application, configure reports that it can't find GTK.
-<p>
-There are several common reasons for this:
-<itemize>
-<item>You have an old version of GTK installed somewhere. RedHat 5.0, for
-example, installs an older copy of GTK that may not work with the latest
-applications. You should remove this old copy, but note that in the case
-of RedHat 5.0 this will break the <tt/control-panel/ applications.
-<P>
-<item><tt/gtk-config/ (or another component of GTK) isn't in your path, or
-there is an old version on your system. Type:
-<verb>
-gtk-config --version
-</verb>
-to check for both of these. If it returns a value different from what
-you expect, then you have an old version of GTK on your system.
-<P>
-<item>The ./configure script can't find the GTK libraries. As ./configure
-compiles various test programs, it needs to be able to find the GTK
-libraries. See the question above for help on this.
-</itemize>
-<p>
-If none of the above help, then have a look in config.log, which is
-generated by ./configure as it runs. At the bottom will be the last
-action it took before failing. If it is a section of source code, copy
-the source code to a file and compile it with the line just above it in
-config.log. If the compilation is successful, try executing it.
-
-<!-- ***************************************************************** -->
-<sect>Development of GTK+
-<!-- ***************************************************************** -->
-
-<!-- ----------------------------------------------------------------- -->
-<sect1>Whats this CVS thing that everyone keeps talking about, and how do I access it?
-<p>
-CVS is the Concurent Version System and is a very popular means of
-version control for software projects. It is designed to allow multiple
-authors to be able to simultanously operate on the same source tree.
-This source tree is centrally maintained, but each developer has a
-local mirror of this repository that they make there changes to.
-
-The GTK+ developers use a CVS repository to store the master copy of
-the current development version of GTK+. As such, people wishing to
-contribute patches to GTK+ should generate them against the CVS version.
-Normal people should use the packaged releases.
-
-The CVS toolset is available as RPM packages from the usual RedHat sites.
-The latest version is available at
-<htmlurl url="http://download.cyclic.com/pub/"
-name="http://download.cyclic.com/pub/">
-
-Anyone can download the latest CVS version of GTK+ by using anonymous access
-using the following steps:
-<itemize>
-<item> In a bourne shell descendant (e.g. bash) type:
-<verb>
-CVSROOT=':pserver:anonymous@anoncvs.gnome.org:/cvs/gnome'
-export CVSROOT
-</verb>
-<item>Next, the first time the source tree is checked out, a cvs login
-is needed.
-<verb>
-cvs login
-</verb>
-This will ask you for a password. There is no password for cvs.gimp.org,
-so just enter a carriage return.
-<item>To get the tree and place it in a subdir of your current working
-directory, issue the command:
-<verb>
-cvs -z3 get gtk+
-</verb>
-
-Note that with the GTK+ 1.1 tree, glib has been moved to a separate CVS
-module, so if you don't have glib installed you will need to get that
-as well:
-<verb>
-cvs -z3 get glib
-</verb>
-</itemize>
-
-<!-- ----------------------------------------------------------------- -->
-<sect1>How can I contribute to GTK+?
-<p>
-It's simple. If something doesn't work like you think it should in a program,
-check the documentation to make sure you're not missing something. If it is a
-true bug or missing feature, track it down in the GTK+ source, change it,
-and then generate a patch in the form of a 'context diff'. This can be done
-using a command such as <tt/diff -ru <oldfile> <newfile>/.
-Then upload the patchfile to:
-<verb>
-ftp://ftp.gtk.org/incoming
-</verb>
-along with a README file. Make sure you follow the naming conventions or your
-patch will just be deleted! The filenames should be of this form:
-<verb>
-gtk-<username>-<date yymmdd-n>.patch.gz
-gtk-<username>-<date yymmdd-n>.patch.README
-</verb>
-The "n" in the date indicates a unique number (starting from 0)
-of patches you uploaded that day. It should be 0, unless you
-upload more than one patch in the same day.
-
-Example:
-<verb>
-gtk-gale-982701-0.patch.gz
-gtk-gale-982701-0.patch.README
-</verb>
-Once you upload <em>anything</em>, send the README to ftp-admin@gtk.org
-
-<!-- ----------------------------------------------------------------- -->
-<sect1>How do I know if my patch got applied, and if not, why not?
-<p>
-Uploaded patches will be moved to <tt>ftp://ftp.gtk.org/pub/gtk/patches</tt>
-where one of the GTK+ development team will pick them up. If applied, they
-will be moved to <tt>/pub/gtk/patches/old</tt>.
-
-Patches that aren't applied, for whatever reason, are moved to
-<tt>/pub/gtk/patches/unapplied</tt> or <tt>/pub/gtk/patches/outdated</tt>.
-At this point you can ask on the <tt/gtk-list/ mailing list why your patch
-wasn't applied. There are many possible reasons why patches may not be
-applied, ranging from it doesn't apply cleanly, to it isn't right. Don't
-be put off if your patch didn't make it first time round.
-
-<!-- ----------------------------------------------------------------- -->
-<sect1>What is the policy on incorporating new widgets into the library?
-<p>
-This is up to the authors, so you will have to ask them once you
-are done with your widget. As a general guideline, widgets that are
-generally useful, work, and are not a disgrace to the widget set will
-gladly be included.
-
-<!-- ----------------------------------------------------------------- -->
-<sect1>Is anyone working on bindings for languages other than C?
-<p>
-The GTK+ home page (<htmlurl url="http://www.gtk.org/"
-name="http://www.gtk.org/">) presents a list of GTK+ bindings.
-
-<itemize>
-<item>There are several C++ wrappers for GTK+.
- <itemize>
-
- <item>the gtk-- package, which is a very small wrapper for GTK+.
- You can find the home page at:
- <htmlurl url="http://www.cs.tut.fi/~p150650/gtk/gtk--.html"
- name="http://www.cs.tut.fi/~p150650/gtk/gtk--.html">.
- The FTP site is
- <htmlurl url="ftp://ftp.gtk.org/pub/gtk/gtk--"
- name="ftp://ftp.gtk.org/pub/gtk/gtk--">.
-
- <item>the VDK package, which was built as the base package of a GTK+
- application Borland-like builder. The home page can be found at
- <htmlurl url="www.guest.net/homepages/mmotta/VDKHome"
- name="www.guest.net/homepages/mmotta/VDKHome">.
-
- <item>The wxWindows/Gtk package, a free C++ library for cross-platform
- GUI development. The home page of this package is
- <htmlurl url="http://www.freiburg.linux.de/~wxxt/"
- name="http://www.freiburg.linux.de/~wxxt/">.
-
- </itemize>
-<p>
-
-<item>There are three known Objective-c bindings currently in development:
-
- <itemize>
-
- <item>The <htmlurl url="http://www.gnome.org/" name="GNOME project's"> package
- of choice is objgtk. Objgtk is based on the Object class and is maintained by
- <htmlurl url="mailto:sopwith@cuc.edu" name="Elliot Lee">. Apparently, objgtk
- is being accepted as the `standard' Objective-C binding for GTK+.
-
- <item>If you are more inclined towards the
- <htmlurl url="http://www.gnustep.org/" name="GNUstep project">,
- you may want to check out GTKKit by
- <htmlurl url="mailto:helge@mdlink.de" name="Helge Heß">.
- The intention is to setup a GTK+ binding using the FoundationKit.
- GTKKit includes nicities like writing a XML-type template file to
- construct a GTK+ interface.
-
- <item>The GToolKit package, which can be found at
- <htmlurl url="ftp://ftp.gtk.org/pub/gtk/objc-gtoolkit/"
- name="ftp://ftp.gtk.org/pub/gtk/objc-gtoolkit/">.
-
- </itemize>
-<p>
-<item>Perl bindings
- <htmlurl url="ftp://ftp.gtk.org/pub/gtk/perl"
- name="ftp://ftp.gtk.org/pub/gtk/perl">
-<P>
-<item>Guile bindings. The home page is at
- <htmlurl url="http://www.ping.de/sites/zagadka/guile-gtk"
- name="http://www.ping.de/sites/zagadka/guile-gtk">.
- By the way, Guile is the GNU Project's implemention of R4RS Scheme (the
- standard). If you like Scheme, you may want to take a look at this.
-<p>
-
-<item>David Monniaux reports:
- <quote>I've started a gtk-O'Caml binding system.
- The basics of the system, including callbacks, work fine.
-
- The current development is in
- <htmlurl url="http://www.ens-lyon.fr/~dmonniau/arcs"
- name="http://www.ens-lyon.fr/~dmonniau/arcs">
- </quote>
-
-<item> Several python bindings have been done:
-<p>
- <itemize>
- <item>pygtk is at
- <htmlurl url="http://www.daa.com.au/~james/pygtk"
- name="http://www.daa.com.au/~james/pygtk"> and
- <htmlurl url="ftp://ftp.gtk.org/pub/gtk/python"
- name="ftp://ftp.gtk.org/pub/gtk/python">
-
- <item>python-gtk is at
- <htmlurl url="http://www.ucalgary.ca/~nascheme/python-gtk"
- name="http://www.ucalgary.ca/~nascheme/python-gtk">
- </itemize>
-<p>
-<item>There's are a couple of OpenGL/Mesa widgets available for
-GTK+. I suggest you start at
- <htmlurl url="http://www.student.oulu.fi/~jlof/gtkglarea/index.html"
- name="http://www.student.oulu.fi/~jlof/gtkglarea/index.html">
-<p>
-<item>Last, there are a lot of other language bindings for languages such as
- Eiffel, TOM, Pascal, Pike, etc.
-
-</itemize>
-
-<!-- ***************************************************************** -->
-<sect>Development with GTK+: the begining
-<!-- ***************************************************************** -->
-
-
-<!-- ----------------------------------------------------------------- -->
-<sect1>How do I get started?
-<p>
-So, after you have installed GTK+ there are a couple of things that can
-ease you into developing applications with it. There is the
-GTK+ Tutorial <htmlurl url="http://www.gtk.org/tutorial/"
-name="http://www.gtk.org/tutorial/">, which is undergoing
-development. This will introduce you to writing applications using C.
-
-The Tutorial doesn't (yet) contain information on all of the widgets
-that are in GTK+. For example code on how to use the basics of all the
-GTK+ widgets you should look at the file gtk/testgtk.c (and associated
-source files) within the GTK+ distribution. Looking at these examples will
-give you a good grounding on what the widgets can do.
-
-<!-- ----------------------------------------------------------------- -->
-<sect1>I tried to compile a small <tt/Hello World/ of mine, but it failed. Any clue?
-<p>
-Since you are good at coding, we will not deal with compile time error here :).
-
-The classic command line to compile a GTK+ based program is
-
-<verb>
-gcc -o myprg [c files list] `gtk-config --cflags --libs`
-</verb>
-
-You should notice the backquote character which is used in this command line.
-A common mistake when you start a GTK+ based development is to use quote
-instead of backquotes. If you do so, the compiler will complain about an
-unknown file called 'gtk-config --cflags --libs'. The text in
-backquotes is an instruction to your shell to substitute the output of
-executing this text into the command line.
-
-The command line above ensure that:
-<itemize>
-
- <item>the correct C compiler flags will be used to compile the program
- (including the complete C header directory list)
-
- <item>your program will be linked with the needed libraries.
-
-</itemize>
-
-<!-- ----------------------------------------------------------------- -->
-<sect1>What about using the <tt/make/ utility?
-<p>
-This is a sample makefile which compile a GTK+ based program:
-
-<tscreen><verb>
-# basic GTK+ app makefile
-SOURCES = myprg.c foo.c bar.c
-OBJS = ${SOURCES:.c=.o}
-CFLAGS = `gtk-config --cflags`
-LDADD = `gtk-config --libs`
-CC = gcc
-PACKAGE = myprg
-
-all : ${OBJS}
- ${CC} -o ${PACKAGE} ${OBJS} ${LDADD}
-
-.c.o:
- ${CC} ${CFLAGS} -c $<
-
-# end of file
-</verb></tscreen>
-
-For more information about the <tt/make/ utility, you should read either the
-related man page or the relevant info file.
-
-<sect1>I use the backquote stuff in my makefiles, but my make process failed.
-<p>
-The backquote construction seems to not be accepted by some old <tt/make/
-utilities. If you use one of these, the make process will probably fail.
-In order to have the backquote syntax working again, you should use the
-GNU make utility (get it on the GNU ftp server at
-<htmlurl url="ftp://ftp.gnu.org/" name="ftp://ftp.gnu.org/">).
-
-<!-- ----------------------------------------------------------------- -->
-<sect1>I want to add some configure stuff, how could I do this?
-<p>
-To use autoconf/automake, you must first install the relevant packages. These
-are:
-
-<itemize>
- <item>the m4 preprocessor v1.4 or better
- <item>autoconf v2.13 or better
- <item>automake v1.4 or better
-</itemize>
-
-You'll find these packages on the GNU main ftp server (<htmlurl
-url="ftp://ftp.gnu.org/" name="ftp://ftp.gnu.org/">) or on any GNU mirror.
-
-In order to use the powerful autoconf/automake scheme, you must create
-a configure.in which may look like:
-
-<tscreen><verb>
-dnl Process this file with autoconf to produce a configure script.
-dnl configure.in for a GTK+ based program
-
-AC_INIT(myprg.c)dnl
-AM_INIT_AUTOMAKE(mypkgname,0.0.1)dnl
-AM_CONFIG_HEADER(config.h)dnl
-
-dnl Checks for programs.
-AC_PROG_CC dnl check for the c compiler
-dnl you should add CFLAGS="" here, 'cos it is set to -g by PROG_CC
-
-dnl Checks for libraries.
-AM_PATH_GTK(1.2.0,,AC_MSG_ERROR(mypkgname 0.1 needs GTK))dnl
-
-AC_OUTPUT(
- Makefile
-)dnl
-</verb></tscreen>
-
-You must add a Makefile.am file:
-
-<tscreen><verb>
-bin_PROGRAMS = myprg
-myprg_SOURCES = myprg.c foo.c bar.c
-INCLUDES = @GTK_CFLAGS@
-LDADD = @GTK_LIBS@
-CLEANFILES = *~
-DISTCLEANFILES = .deps/*.P
-</verb></tscreen>
-
-If your project contains more than one subdirectory, you'll have to
-create one Makefile.am in each directory plus a master Makefile.am
-which will look like:
-
-<tscreen><verb>
-SUBDIRS = mydir1 mydir2 mydir3
-</verb></tscreen>
-
-then, to use these, simply type the following commands:
-
-<verb>
-aclocal
-autoheader
-autoconf
-automake --add-missing --include-deps --foreign
-</verb>
-
-For further information, you should look at the autoconf and the
-automake documentation (the shipped info files are really easy to
-understand, and there are plenty of web resources that deal with
-autoconf and automake).
-
-<!-- ----------------------------------------------------------------- -->
-<sect1>I try to debug my GTK+ application with gdb, but it hangs my X server when I hit some breakpoint. Any Idea ?
-<p>
-From Federico Mena Quintero:
-<quote>
-X is not locked up. It is likely that you are hitting a breakpoint
-inside a callback that is called from a place in Gtk that has a mouse
-grab.
-<P>
-Run your program with the "--sync" option; it will make it easier to
-debug. Also, you may want to use the console for running the
-debugger, and just let the program run in another console with the X
-server.
-</quote>
-
-Eric Mouw had another solution:
-<quote>
-An old terminal connected to an otherwise unused serial port is also great
-for debugging X programs. Old vt100/vt220 terminals are dirt cheap but a
-bit hard to get (here in The Netherlands, YMMV).
-</quote>
-
-<!-- ***************************************************************** -->
-<sect>Development with GTK+: general questions
-<!-- ***************************************************************** -->
-
-<!-- ----------------------------------------------------------------- -->
-<sect1>What widgets are in GTK?
-<p>
-The GTK+ Tutorial lists the following widgets:
-
-<verb>
- GtkObject
- +GtkData
- | +GtkAdjustment
- | `GtkTooltips
- `GtkWidget
- +GtkContainer
- | +GtkBin
- | | +GtkAlignment
- | | +GtkEventBox
- | | +GtkFrame
- | | | `GtkAspectFrame
- | | +GtkHandleBox
- | | +GtkItem
- | | | +GtkListItem
- | | | +GtkMenuItem
- | | | | `GtkCheckMenuItem
- | | | | `GtkRadioMenuItem
- | | | `GtkTreeItem
- | | +GtkViewport
- | | `GtkWindow
- | | +GtkColorSelectionDialog
- | | +GtkDialog
- | | | `GtkInputDialog
- | | `GtkFileSelection
- | +GtkBox
- | | +GtkButtonBox
- | | | +GtkHButtonBox
- | | | `GtkVButtonBox
- | | +GtkHBox
- | | | +GtkCombo
- | | | `GtkStatusbar
- | | `GtkVBox
- | | +GtkColorSelection
- | | `GtkGammaCurve
- | +GtkButton
- | | +GtkOptionMenu
- | | `GtkToggleButton
- | | `GtkCheckButton
- | | `GtkRadioButton
- | +GtkCList
- | `GtkCTree
- | +GtkFixed
- | +GtkList
- | +GtkMenuShell
- | | +GtkMenuBar
- | | `GtkMenu
- | +GtkNotebook
- | +GtkPaned
- | | +GtkHPaned
- | | `GtkVPaned
- | +GtkScrolledWindow
- | +GtkTable
- | +GtkToolbar
- | `GtkTree
- +GtkDrawingArea
- | `GtkCurve
- +GtkEditable
- | +GtkEntry
- | | `GtkSpinButton
- | `GtkText
- +GtkMisc
- | +GtkArrow
- | +GtkImage
- | +GtkLabel
- | | `GtkTipsQuery
- | `GtkPixmap
- +GtkPreview
- +GtkProgressBar
- +GtkRange
- | +GtkScale
- | | +GtkHScale
- | | `GtkVScale
- | `GtkScrollbar
- | +GtkHScrollbar
- | `GtkVScrollbar
- +GtkRuler
- | +GtkHRuler
- | `GtkVRuler
- `GtkSeparator
- +GtkHSeparator
- `GtkVSeparator
-</verb>
-
-<!-- ----------------------------------------------------------------- -->
-<sect1>Is GTK+ thread safe? How do I write multi-threaded GTK+ applications?
-<p>
-The GLib library can be used in a thread-safe mode by calling
-g_thread_init() before making any other GLib calls. In this mode GLib
-automatically locks all internal data structures as needed. This
-does not mean that two threads can simultaneously access, for
-example, a single hash table, but they can access two different hash
-tables simultaneously. If two different threads need to access the
-same hash table, the application is responsible for locking
-itself.
-
-When GLib is intialized to be thread-safe, GTK+ is
-<em>thread aware</em>. There is a single global lock
-that you must acquire with gdk_threads_enter() before
-making any GDK calls, and release with gdk_threads_leave()
-afterwards.
-
-A minimal main program for a threaded GTK+ application
-looks like:
-
-<verb>
-int
-main (int argc, char *argv[])
-{
- GtkWidget *window;
-
- g_thread_init(NULL);
- gtk_init(&argc, &argv);
-
- window = create_window();
- gtk_widget_show(window);
-
- gdk_threads_enter();
- gtk_main();
- gdk_threads_leave();
-
- return(0);
-}
-</verb>
-
-Callbacks require a bit of attention. Callbacks from GTK+
-(signals) are made within the GTK+ lock. However callbacks
-from GLib (timeouts, IO callbacks, and idle functions)
-are made outside of the GTK+ lock. So, within a signal
-handler you do not need to call gdk_threads_enter(), but
-within the other types of callbacks, you do.
-
-Erik Mouw contributed the following code example to illustrate how to
-use threads within GTK+ programs.
-
-<tscreen><verb>
-/*-------------------------------------------------------------------------
- * Filename: gtk-thread.c
- * Version: 0.99.1
- * Copyright: Copyright (C) 1999, Erik Mouw
- * Author: Erik Mouw <J.A.K.Mouw@its.tudelft.nl>
- * Description: GTK threads example.
- * Created at: Sun Oct 17 21:27:09 1999
- * Modified by: Erik Mouw <J.A.K.Mouw@its.tudelft.nl>
- * Modified at: Sun Oct 24 17:21:41 1999
- *-----------------------------------------------------------------------*/
-/*
- * Compile with:
- *
- * cc -o gtk-thread gtk-thread.c `gtk-config --cflags --libs gthread`
- *
- * Thanks to Sebastian Wilhelmi and Owen Taylor for pointing out some
- * bugs.
- *
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <time.h>
-#include <gtk/gtk.h>
-#include <glib.h>
-#include <pthread.h>
-
-#define YES_IT_IS (1)
-#define NO_IT_IS_NOT (0)
-
-typedef struct
-{
- GtkWidget *label;
- int what;
-} yes_or_no_args;
-
-G_LOCK_DEFINE_STATIC (yes_or_no);
-static volatile int yes_or_no = YES_IT_IS;
-
-void destroy(GtkWidget *widget, gpointer data)
-{
- gtk_main_quit();
-}
-
-void *argument_thread(void *args)
-{
- yes_or_no_args *data = (yes_or_no_args *)args;
- gboolean say_something;
-
- for(;;)
- {
- /* sleep a while */
- sleep(rand() / (RAND_MAX / 3) + 1);
-
- /* lock the yes_or_no_variable */
- G_LOCK(yes_or_no);
-
- /* do we have to say something? */
- say_something = (yes_or_no != data->what);
-
- if(say_something)
- {
- /* set the variable */
- yes_or_no = data->what;
- }
-
- /* Unlock the yes_or_no variable */
- G_UNLOCK(yes_or_no);
-
- if(say_something)
- {
- /* get GTK thread lock */
- gdk_threads_enter();
-
- /* set label text */
- if(data->what == YES_IT_IS)
- gtk_label_set_text(GTK_LABEL(data->label), "O yes, it is!");
- else
- gtk_label_set_text(GTK_LABEL(data->label), "O no, it isn't!");
-
- /* release GTK thread lock */
- gdk_threads_leave();
- }
- }
-
- return(NULL);
-}
-
-int main(int argc, char *argv[])
-{
- GtkWidget *window;
- GtkWidget *label;
- yes_or_no_args yes_args, no_args;
- pthread_t no_tid, yes_tid;
-
- /* init threads */
- g_thread_init(NULL);
-
- /* init gtk */
- gtk_init(&argc, &argv);
-
- /* init random number generator */
- srand((unsigned int)time(NULL));
-
- /* create a window */
- window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
-
- gtk_signal_connect(GTK_OBJECT (window), "destroy",
- GTK_SIGNAL_FUNC(destroy), NULL);
-
- gtk_container_set_border_width(GTK_CONTAINER (window), 10);
-
- /* create a label */
- label = gtk_label_new("And now for something completely different ...");
- gtk_container_add(GTK_CONTAINER(window), label);
-
- /* show everything */
- gtk_widget_show(label);
- gtk_widget_show (window);
-
- /* create the threads */
- yes_args.label = label;
- yes_args.what = YES_IT_IS;
- pthread_create(&yes_tid, NULL, argument_thread, &yes_args);
-
- no_args.label = label;
- no_args.what = NO_IT_IS_NOT;
- pthread_create(&no_tid, NULL, argument_thread, &no_args);
-
- /* enter the GTK main loop */
- gdk_threads_enter();
- gtk_main();
- gdk_threads_leave();
-
- return(0);
-}
-</verb></tscreen>
-
-<!-- This is the old answer - TRG
-
-Although GTK+, like many X toolkits, isn't thread safe, this does
-not prohibit the development of multi-threaded applications with
-GTK+.
-
-Rob Browning (rlb@cs.utexas.edu) describes threading techniques for
-use with GTK+ (slightly edited):
-
-There are basically two main approaches, the first is simple, and the
-second complicated. In the first, you just make sure that all GTK+ (or
-X) interactions are handled by one, and
-only one, thread. Any other thread that wants to draw something has
-to somehow notify the "GTK+" thread, and let it handle the
-actual work.
-
-The second approach allows you to call GTK+ (or X) functions from any
-thread, but it requires some careful synchronization. The
-basic idea is that you create an X protection mutex, and no one may
-make any X calls without first acquiring this mutex.
-
-Note that this is a little effort, but it allows you to be
-potentially more efficient than a completely thread safe GTK+. You
-get to decide the granularity of the thread locking. You also have to
-make sure that the thread that calls <tt/gtk_main()/ is holding the lock when
-it calls <tt/gtk_main()/.
-
-The next thing to worry about is that since you were holding the
-global mutex when you entered <tt/gtk_main()/, all callbacks will also be
-holding it. This means that the callback must release it if it's
-going to call any other code that might reacquire it. Otherwise
-you'll get deadlock. Also, you must be holding the mutex when you
-finally return from the callback.
-
-In order to allow threads other than the one calling <tt/gtk_main/ to
-get access to the mutex, we also need to register a work function
-with GTK that allows us to release the mutex periodically.
-
-Why can't GTK+ be thread safe by default?
-
-Complexity, overhead, and manpower. The proportion of threaded
-programs is still reasonably small, and getting thread safety right is
-both quite difficult and takes valuable time away from the main work
-of getting a good graphics library finished. It would be nice to have
-GTK+ thread safe "out of the box", but that's not practical right now,
-and it also might make GTK+ substantially less efficient if not handled
-carefully.
-
-Regardless, it's especially not a priority since relatively good
-workarounds exist.
--->
-
-<!-- ----------------------------------------------------------------- -->
-<sect1>Why does this strange 'x io error' occur when I <tt/fork()/ in my GTK+ app?
-<p>
-This is not really a GTK+ problem, and the problem is not related to
-<tt/fork()/ either. If the 'x io error' occurs then you probably use
-the <tt/exit()/ function in order to exit from the child process.
-
-When GDK opens an X display, it creates a socket file descriptor. When
-you use the <tt/exit()/ function, you implicitly close all the open
-file descriptors, and the underlying X library really doesn't like
-this.
-
-The right function to use here is <tt/_exit()/.
-
-Erik Mouw contributed the following code example to illustrate
-handling fork() and exit().
-
-<tscreen><verb>
-/*-------------------------------------------------------------------------
- * Filename: gtk-fork.c
- * Version: 0.99.1
- * Copyright: Copyright (C) 1999, Erik Mouw
- * Author: Erik Mouw <J.A.K.Mouw@its.tudelft.nl>
- * Description: GTK+ fork example
- * Created at: Thu Sep 23 21:37:55 1999
- * Modified by: Erik Mouw <J.A.K.Mouw@its.tudelft.nl>
- * Modified at: Thu Sep 23 22:39:39 1999
- *-----------------------------------------------------------------------*/
-/*
- * Compile with:
- *
- * cc -o gtk-fork gtk-fork.c `gtk-config --cflags --libs`
- *
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <signal.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <unistd.h>
-#include <gtk/gtk.h>
-
-void sigchld_handler(int num)
-{
- sigset_t set, oldset;
- pid_t pid;
- int status, exitstatus;
-
- /* block other incoming SIGCHLD signals */
- sigemptyset(&set);
- sigaddset(&set, SIGCHLD);
- sigprocmask(SIG_BLOCK, &set, &oldset);
-
- /* wait for child */
- while((pid = waitpid((pid_t)-1, &status, WNOHANG)) > 0)
- {
- if(WIFEXITED(status))
- {
- exitstatus = WEXITSTATUS(status);
-
- fprintf(stderr,
- "Parent: child exited, pid = %d, exit status = %d\n",
- (int)pid, exitstatus);
- }
- else if(WIFSIGNALED(status))
- {
- exitstatus = WTERMSIG(status);
-
- fprintf(stderr,
- "Parent: child terminated by signal %d, pid = %d\n",
- exitstatus, (int)pid);
- }
- else if(WIFSTOPPED(status))
- {
- exitstatus = WSTOPSIG(status);
-
- fprintf(stderr,
- "Parent: child stopped by signal %d, pid = %d\n",
- exitstatus, (int)pid);
- }
- else
- {
- fprintf(stderr,
- "Parent: child exited magically, pid = %d\n",
- (int)pid);
- }
- }
-
- /* re-install the signal handler (some systems need this) */
- signal(SIGCHLD, sigchld_handler);
-
- /* and unblock it */
- sigemptyset(&set);
- sigaddset(&set, SIGCHLD);
- sigprocmask(SIG_UNBLOCK, &set, &oldset);
-}
-
-gint delete_event(GtkWidget *widget, GdkEvent *event, gpointer data)
-{
- return(FALSE);
-}
-
-void destroy(GtkWidget *widget, gpointer data)
-{
- gtk_main_quit();
-}
-
-void fork_me(GtkWidget *widget, gpointer data)
-{
- pid_t pid;
-
- pid = fork();
-
- if(pid == -1)
- {
- /* ouch, fork() failed */
- perror("fork");
- exit(-1);
- }
- else if(pid == 0)
- {
- /* child */
- fprintf(stderr, "Child: pid = %d\n", (int)getpid());
-
- execlp("ls", "ls", "-CF", "/", NULL);
-
- /* if exec() returns, there is something wrong */
- perror("execlp");
-
- /* exit child. note the use of _exit() instead of exit() */
- _exit(-1);
- }
- else
- {
- /* parent */
- fprintf(stderr, "Parent: forked a child with pid = %d\n", (int)pid);
- }
-}
-
-int main(int argc, char *argv[])
-{
- GtkWidget *window;
- GtkWidget *button;
-
- gtk_init(&argc, &argv);
-
- /* the basic stuff: make a window and set callbacks for destroy and
- * delete events
- */
- window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
-
- gtk_signal_connect(GTK_OBJECT (window), "delete_event",
- GTK_SIGNAL_FUNC(delete_event), NULL);
-
- gtk_signal_connect(GTK_OBJECT (window), "destroy",
- GTK_SIGNAL_FUNC(destroy), NULL);
-
-#if (GTK_MAJOR_VERSION == 1) && (GTK_MINOR_VERSION == 0)
- gtk_container_border_width(GTK_CONTAINER (window), 10);
-#else
- gtk_container_set_border_width(GTK_CONTAINER (window), 10);
-#endif
-
- /* add a button to do something useful */
- button = gtk_button_new_with_label("Fork me!");
-
- gtk_signal_connect(GTK_OBJECT (button), "clicked",
- GTK_SIGNAL_FUNC(fork_me), NULL);
-
- gtk_container_add(GTK_CONTAINER(window), button);
-
- /* show everything */
- gtk_widget_show (button);
- gtk_widget_show (window);
-
-
- /* install a signal handler for SIGCHLD signals */
- signal(SIGCHLD, sigchld_handler);
-
-
- /* main loop */
- gtk_main ();
-
- exit(0);
-}
-</verb></tscreen>
-
-<!-- ----------------------------------------------------------------- -->
-<sect1>Why don't the contents of a button move when the button is pressed? Here's a patch to make it work that way...
-<p>
-From: Peter Mattis
-
-<quote>
-The reason buttons don't move their child down and to the right when
-they are depressed is because I don't think that's what is happening
-visually. My view of buttons is that you are looking at them straight
-on. That is, the user interface lies in a plane and you're above it
-looking straight at it. When a button gets pressed it moves directly
-away from you. To be absolutely correct I guess the child should
-actually shrink a tiny amount. But I don't see why the child should
-shift down and to the left. Remember, the child is supposed to be
-attached to the buttons surface. Its not good for it to appear like
-the child is slipping on the surface of the button.
-<P>
-On a more practical note, I did implement this at one point and
-determined it didn't look good and removed it.
-</quote>
-
-<!-- ----------------------------------------------------------------- -->
-<sect1>How to I identifiy a widgets top level window or other ancestor?
-<p>
-There are a couple of ways to find the top level parent of a
-widget. The easier way is to call the <tt/gtk_widget_top_level()/
-function that returns a pointer to a GtkWidget that is the top level
-window.
-
-A more complicated way to do this (but less limited, as it allows
-the user to get the closest ancestor of a known type) is to use
-<tt/gtk_widget_get_ancestor()/ as in:
-
-<tscreen><verb>
- GtkWidget *widget;
-
- widget = gtk_widget_get_ancestor(w, GTK_TYPE_WINDOW);
-</verb></tscreen>
-
-Since virtually all the GTK_TYPEs can be used as the second parameter
-of this function, you can get any parent widget of a particular
-widget. Suppose you have an hbox which contains a vbox, which in turn
-contains some other atomic widget (entry, label, etc. To find the
-master hbox using the <tt/entry/ widget simply use:
-
-<tscreen><verb>
- GtkWidget *hbox;
- hbox = gtk_widget_get_ancestor(w, GTK_TYPE_HBOX);
-</verb></tscreen>
-
-<!-- ----------------------------------------------------------------- -->
-<sect1>How do I get the Window ID of a GtkWindow?
-<p>
-The actual Gdk/X window will be created when the widget gets
-realized. You can get the Window ID with:
-
-<verb>
-#include <gdk/gdkx.h>
-
-Window xwin = GDK_WINDOW_XWINDOW (GTK_WIDGET (my_window)->window);
-</verb>
-
-<!-- ----------------------------------------------------------------- -->
-<sect1>How do I catch a double click event (in a list widget, for example)?
-<p>
-Tim Janik wrote to gtk-list (slightly modified):
-
-Define a signal handler:
-
-<tscreen><verb>
-gint
-signal_handler_event(GtkWiget *widget, GdkEvenButton *event, gpointer func_data)
-{
- if (GTK_IS_LIST_ITEM(widget) &&
- (event->type==GDK_2BUTTON_PRESS ||
- event->type==GDK_3BUTTON_PRESS) ) {
- printf("I feel %s clicked on button %d\",
- event->type==GDK_2BUTTON_PRESS ? "double" : "triple",
- event->button);
- }
-
- return FALSE;
-}
-</verb></tscreen>
-
-And connect the handler to your object:
-
-<tscreen><verb>
-{
- /* list, list item init stuff */
-
- gtk_signal_connect(GTK_OBJECT(list_item),
- "button_press_event",
- GTK_SIGNAL_FUNC(signal_handler_event),
- NULL);
-
- /* and/or */
-
- gtk_signal_connect(GTK_OBJECT(list_item),
- "button_release_event",
- GTK_SIGNAL_FUNC(signal_handler_event),
- NULL);
-
- /* something else */
-}
-</verb></tscreen>
-
-and, Owen Taylor wrote:
-
-Note that a single button press will be received beforehand, and
-if you are doing this for a button, you will therefore also get a
-"clicked" signal for the button. (This is going to be true for
-any toolkit, since computers aren't good at reading one's
-mind.)
-
-<!-- ----------------------------------------------------------------- -->
-<sect1>By the way, what are the differences between signals and events?
-<p>
-First of all, Havoc Pennington gives a rather complete description of
-the differences between events and signals in his free book (two
-chapters can be found at <htmlurl
-url="http://www106.pair.com/rhp/sample_chapters.html"
-name="http://www106.pair.com/rhp/sample_chapters.html">).
-
-Moreover, Havoc posted this to the <tt/gtk-list/
-<quote>
- Events are a stream of messages received from the X server. They
- drive the Gtk main loop; which more or less amounts to "wait for
- events, process them" (not exactly, it is really more general than
- that and can wait on many different input streams at once). Events
- are a Gdk/Xlib concept.
-<P>
- Signals are a feature of GtkObject and its subclasses. They have
- nothing to do with any input stream; really a signal is just a way
- to keep a list of callbacks around and invoke them ("emit" the
- signal). There are lots of details and extra features of
- course. Signals are emitted by object instances, and are entirely
- unrelated to the Gtk main loop. Conventionally, signals are emitted
- "when something changes" about the object emitting the signal.
-<P>
- Signals and events only come together because GtkWidget happens to
- emit signals when it gets events. This is purely a convenience, so
- you can connect callbacks to be invoked when a particular widget
- receives a particular event. There is nothing about this that makes
- signals and events inherently related concepts, any more than
- emitting a signal when you click a button makes button clicking and
- signals related concepts.
-</quote>
-
-<!-- ----------------------------------------------------------------- -->
-<sect1>Data I pass to the <tt/delete_event/ (or other event) handler gets corrupted.
-<p>
-All event handlers take an additional argument which contains
-information about the event that triggered the handler. So, a
-<tt/delete_event/ handler must be declared as:
-
-<tscreen><verb>
-gint delete_event_handler (GtkWidget *widget,
- GdkEventAny *event,
- gpointer data);
-</verb></tscreen>
-
-<!-- ----------------------------------------------------------------- -->
-<sect1>I have my signal connected to the the (whatever) event, but it seems I don't catch it. What's wrong?
-<p>
-There is some special initialisation to do in order to catch some
-particular events. In fact, you must set the correct event mask bit of
-your widget before getting some particular events.
-
-For example,
-
-<tscreen><verb>
- gtk_widget_add_events(window, GDK_KEY_RELEASE_MASK);
-</verb></tscreen>
-
-lets you catch the key release events. If you want to catch every events,
-simply us the GDK_ALL_EVENTS_MASK event mask.
-
-All the event masks are defined in the <tt/gdktypes.h/ file.
-
-<!-- ----------------------------------------------------------------- -->
-<sect1>I need to add a new signal to a GTK+ widget. Any idea?
-<p>
-If the signal you want to add may be beneficial for other GTK+ users,
-you may want to submit a patch that presents your changes. Check the
-tutorial for more information about adding signals to a widget class.
-
-If you don't think it is the case or if your patch is not applied
-you'll have to use the <tt/gtk_object_class_user_signal_new/
-function. <tt/gtk_object_class_user_signal_new/ allows you to add a
-new signal to a predefined GTK+ widget without any modification of the
-GTK+ source code. The new signal can be emited with
-<tt/gtk_signal_emit/ and can be handled in the same way as other
-signals.
-
-Tim Janik posted this code snippet:
-
-<tscreen><verb>
-static guint signal_user_action = 0;
-
-signal_user_action =
- gtk_object_class_user_signal_new (gtk_type_class (GTK_TYPE_WIDGET),
- "user_action",
- GTK_RUN_LAST | GTK_RUN_ACTION,
- gtk_marshal_NONE__POINTER,
- GTK_TYPE_NONE, 1,
- GTK_TYPE_POINTER);
-
-void
-gtk_widget_user_action (GtkWidget *widget,
- gpointer act_data)
-{
- g_return_if_fail (GTK_IS_WIDGET (widget));
-
- gtk_signal_emit (GTK_OBJECT (widget), signal_user_action, act_data);
-}
-</verb></tscreen>
-
-If you want your new signal to have more than the classical gpointer
-parameter, you'll have to play with GTK+ marshallers.
-
-<!-- ----------------------------------------------------------------- -->
-<sect1>Is it possible to get some text displayed which is truncated to fit inside its allocation?
-<p>
-GTK's behavior (no clipping) is a consequence of its attempts to
-conserve X resources. Label widgets (among others) don't get their own
-X window - they just draw their contents on their parent's window.
-While it might be possible to have clipping occur by setting the clip
-mask before drawing the text, this would probably cause a substantial
-performance penalty.
-
-Its possible that, in the long term, the best solution to such
-problems might be just to change gtk to give labels X windows.
-A short term workaround is to put the label widget inside another
-widget that does get its own window - one possible candidate would
-be the viewport widget.
-
-<tscreen><verb>
-viewport = gtk_viewport (NULL, NULL);
-gtk_widget_set_usize (viewport, 50, 25);
-gtk_viewport_set_shadow_type (GTK_VIEWPORT(viewport), GTK_SHADOW_NONE);
-gtk_widget_show(viewport);
-
-label = gtk_label ("a really long label that won't fit");
-gtk_container_add (GTK_CONTAINER(viewport), label);
-gtk_widget_show (label);
-</verb></tscreen>
-
-If you were doing this for a bunch of widgets, you might want to
-copy gtkviewport.c and strip out the adjustment and shadow
-functionality (perhaps you could call it GtkClipper).
-
-<!-- ----------------------------------------------------------------- -->
-
-<sect1>How do I make my window modal? / How do I make a single window active?
-<p>
-After you create your window, do <tt/gtk_grab_add(my_window)/. And after
-closing the window do <tt/gtk_grab_remove(my_window)/.
-
-<!-- ----------------------------------------------------------------- -->
-<sect1>Why doesn't my widget (e.g. progressbar) update?
-<p>
-
-You are probably doing all the changes within a function without
-returning control to <tt/gtk_main()/. This may be the case if you do
-some lengthy calculation in your code. Most drawing updates are only
-placed on a queue, which is processed within <tt/gtk_main()/. You can
-force the drawing queue to be processed using something like:
-
-<tscreen><verb>
-while (g_main_iteration(FALSE));
-</verb></tscreen>
-
-inside you're function that changes the widget.
-
-What the above snippet does is run all pending events and high priority
-idle functions, then return immediately (the drawing is done in a
-high priority idle function).
-
-<!-- ----------------------------------------------------------------- -->
-<sect1>How do I attach data to some GTK+ object/widget?
-<p>
-First of all, the attached data is stored in the object_data field of
-a GtkObject. The type of this field is GData, which is defined in
-glib.h. So you should read the gdataset.c file in your glib source
-directory very carefully.
-
-There are two (easy) ways to attach some data to a gtk object. Using
-<tt/gtk_object_set_data()/ and <tt/gtk_object_get_data()/ seems to be
-the most common way to do this, as it provides a powerful interface to
-connect objects and data.
-
-<tscreen><verb>
-void gtk_object_set_data(GtkObject *object, const gchar *key, gpointer data);
-
-gpointer gtk_object_get_data(GtkObject *object, const gchar *key);
-</verb></tscreen>
-
-Since a short example is better than any lengthy speech:
-
-<tscreen><verb>
-struct my_struct p1,p2,*result;
-GtkWidget *w;
-
-gtk_object_set_data(GTK_OBJECT(w),"p1 data",(gpointer)&p1);
-gtk_object_set_data(GTK_OBJECT(w),"p2 data",(gpointer)&p2);
-
-result = gtk_object_get_data(GTK_OBJECT(w),"p1 data");
-</verb></tscreen>
-
-The <tt/gtk_object_set_user_data()/ and <tt/gtk_object_get_user_data()/
-functions does exactly the same thing
-as the functions above, but does not let you specify the "key" parameter.
-Instead, it uses a standard "user_data" key. Note that the use of these
-functions is deprecated in 1.2. They only provide a compatibility mode
-with some old gtk packages.
-
-<!-- ----------------------------------------------------------------- -->
-<sect1>How do I remove the data I have attached to an object?
-<p>
-When attaching the data to the object, you can use the
-<tt/gtk_object_set_data_full()/ function. The three first arguments of
-the function are the same as in <tt/gtk_object_set_data()/. The fourth
-one is a pointer to a callback function which is called when the data
-is destroyed. The data is destroyed when you:
-
-<itemize>
-<item> destroy the object
-<item> replace the data with a new one (with the same key)
-<item> replace the data with NULL (with the same key)
-</itemize>
-
-<!-- ----------------------------------------------------------------- -->
-<sect1>How do I reparent a widget?
-<p>
-The normal way to reparent (ie change the owner) of a widget should be
-to use the function:
-
-<tscreen><verb>
-void gtk_widget_reparent (GtkWidget *widget,
- GtkWidget *new_parent)
-</verb></tscreen>
-
-But this is only a "should be" since this function does not correctly
-do its job on some specific widgets. The main goal of
-gtk_widget_reparent() is to avoid unrealizing widget if both widget
-and new_parent are realized (in this case, widget->window is
-successfully reparented). The problem here is that some widgets in the
-GTK+ hierarchy have multiple attached X subwindows and this is notably
-the case for the GtkSpinButton widget. For those,
-gtk_widget_reparent() will fail by leaving an unrealized child window
-where it should not.
-
-To avoid this problem, simply use the following code snippet:
-
-<tscreen><verb>
- gtk_widget_ref(widget);
- gtk_container_remove(GTK_CONTAINER(old_parent), widget);
- gtk_container_add(GTK_CONTAINER(new_parent), widget);
- gtk_widget_unref(widget);
-</verb></tscreen>
-
-<!-- ----------------------------------------------------------------- -->
-<sect1>How could I get any widgets position?
-<p>
-As Tim Janik pointed out, there are different cases, and each case
-requires a different solution.
-
-<itemize>
-<item> If you want the position of a widget relative to its parent,
- you should use <tt/widget->allocation.x/ and
- <tt/widget->allocation.y/.
-<item> If you want the position of a window relative to the X root
- window, you should use <tt/gdk_window_get_geometry()/
- <tt/gdk_window_get_position()/ or
- <tt/gdk_window_get_origin()/.
-<item> If you want to get the position of the window (including the WM
- decorations), you should use
- <tt/gdk_window_get_root_origin()/.
-<item> Last but not least, if you want to get a Window Manager frame
- position, you should use
- <tt/gdk_window_get_deskrelative_origin()/.
-</itemize>
-
-Your choice of Window Manager will have an effect of the results of
-the above functions. You should keep this in mind when writing your
-application. This is dependant upon how the Window Managers manage the
-decorations that they add around windows.
-
-<!-- ----------------------------------------------------------------- -->
-<sect1>How do I set the size of a widget/window? How do I prevent the user resizing my window?
-<p>
-The <tt/gtk_widget_set_uposition()/ function is used to set the
-position of any widget.
-
-The <tt/gtk_widget_set_usize()/ function is used to set the size of a
-widget. In order to use all the features that are provided by this
-function when it acts on a window, you may want to use the
-<tt/gtk_window_set_policy/ function. The definition of these functions
-are:
-
-<tscreen><verb>
-void gtk_widget_set_usize (GtkWidget *widget,
- gint width,
- gint height);
-
-void gtk_window_set_policy (GtkWindow *window,
- gint allow_shrink,
- gint allow_grow,
- gint auto_shrink);
-</verb></tscreen>
-
-<tt/Auto_shrink/ will automatically shrink the window when the
-requested size of the child widgets goes below the current size of the
-window. <tt/Allow_shrink/ will give the user the authorisation to make
-the window smaller that it should normally be. <tt/Allow_grow/ will
-give the user will have the ability to make the window bigger. The
-default values for these parameters are:
-
-<tscreen><verb>
-allow_shrink = FALSE
-allow_grow = TRUE
-auto_shrink = FALSE
-</verb></tscreen>
-
-The <tt/gtk_widget_set_usize()/ functions is not the easiest way to
-set a window size since you cannot decrease this window size with
-another call to this function unless you call it twice, as in:
-
-<tscreen><verb>
- gtk_widget_set_usize(your_widget, -1, -1);
- gtk_widget_set_usize(your_widget, new_x_size, new_y_size);
-</verb></tscreen>
-
-Another way to set the size of and/or move a window is to use the
-<tt/gdk_window_move_resize()/ function which uses to work fine both to
-grow or to shrink the window:
-
-<tscreen><verb>
- gdk_window_move_resize(window->window,
- x_pos, y_pos,
- x_size, y_size);
-</verb></tscreen>
-
-<!-- ----------------------------------------------------------------- -->
-<sect1>How do I add a popup menu to my GTK+ application?
-<p>
-The <tt/menu/ example in the examples/menu directory of the GTK+ distribution
-implements a popup menu with this technique :
-
-<tscreen><verb>
-static gint button_press (GtkWidget *widget, GdkEvent *event)
-{
-
- if (event->type == GDK_BUTTON_PRESS) {
- GdkEventButton *bevent = (GdkEventButton *) event;
- gtk_menu_popup (GTK_MENU(widget), NULL, NULL, NULL, NULL,
- bevent->button, bevent->time);
- /* Tell calling code that we have handled this event; the buck
- * stops here. */
- return TRUE;
- }
-
- /* Tell calling code that we have not handled this event; pass it on. */
- return FALSE;
-}
-</verb></tscreen>
-
-<!-- ----------------------------------------------------------------- -->
-<sect1>How do I disable or enable a widget, such as a button?
-<p>
-To disable (or to enable) a widget, use the
-<tt/gtk_widget_set_sensitive()/ function. The first parameter is you
-widget pointer. The second parameter is a boolean value: when this
-value is TRUE, the widget is enabled.
-
-<!-- ----------------------------------------------------------------- -->
-<sect1>Shouldn't the text argument in the gtk_clist_* functions be declared const?
-<p>
-For example:
-<verb>
-gint gtk_clist_prepend (GtkCList *clist,
- gchar *text[]);
-</verb>
-
-Answer: No, while a type "gchar*" (pointer to char) can automatically
-be cast into "const gchar*" (pointer to const char), this does not
-apply for "gchar *[]" (array of an unspecified number of pointers to
-char) into "const gchar *[]" (array of an unspecified number of
-pointers to const char).
-
-The type qualifier "const" may be subject to automatic casting, but in
-the array case, it is not the array itself that needs the (const)
-qualified cast, but its members, thus changing the whole type.
-
-<!-- ----------------------------------------------------------------- -->
-<sect1>How do I render pixels (image data) to the screen?
-<p>
-There are several ways to approach this. The simplest way is to use
-GdkRGB, see gdk/gdkrgb.h. You create an RGB buffer, render to your RGB
-buffer, then use GdkRGB routines to copy your RGB buffer to a drawing
-area or custom widget. The book "GTK+/Gnome Application Development"
-gives some details; GdkRGB is also documented in the GTK+ reference
-documentation.
-
-If you're writing a game or other graphics-intensive application, you
-might consider a more elaborate solution. OpenGL is the graphics
-standard that will let you access hardware accelaration in future
-versions of XFree86; so for maximum speed, you probably want to use
-OpenGL. A GtkGLArea widget is available for using OpenGL with GTK+
-(but GtkGLArea does not come with GTK+ itself). There are also several
-open source game libraries, such as ClanLib and Loki's Simple
-DirectMedia Layer library (SDL).
-
-You do NOT want to use <tt/gdk_draw_point()/, that will be extremely
-slow.
-
-<!-- ----------------------------------------------------------------- -->
-<sect1>How do I create a pixmap without having my window realized/shown?
-<p>
-Functions such as <tt/gdk_pixmap_create_from_xpm()/ require a valid
-window as a parameter. During the initialisation phase of an
-application, a valid window may not be available without showing a
-window, which may be inappropriate. In order to avoid this, a
-function such as <tt/gdk_pixmap_colormap_create_from_xpm/ can be used,
-as in:
-
-<tscreen><verb>
- char *pixfile = "foo.xpm";
- GtkWidget *top, *box, *pixw;
- GdkPixmap *pixmap, *pixmap_mask;
-
- top = gtk_window_new (GKT_WINDOW_TOPLEVEL);
- box = gtk_hbox_new (FALSE, 4);
- gtk_conainer_add (GTK_CONTAINER(top), box);
-
- pixmap = gdk_pixmap_colormap_create_from_xpm (
- NULL, gtk_widget_get_colormap(top),
- &pixmap_mask, NULL, pixfile);
- pixw = gtk_pixmap_new (pixmap, pixmap_mask);
- gdk_pixmap_unref (pixmap);
- gdk_pixmap_unref (pixmap_mask);
-
-</verb></tscreen>
-
-<!-- ***************************************************************** -->
-<sect>Development with GTK+: widget specific questions
-<!-- ***************************************************************** -->
-
-<!-- ----------------------------------------------------------------- -->
-<sect1>How do I find out about the selection of a GtkList?
-<p>
-Get the selection something like this:
-<tscreen><verb>
-GList *sel;
-sel = GTK_LIST(list)->selection;
-</verb></tscreen>
-
-This is how GList is defined (quoting glist.h):
-<tscreen><verb>
-typedef struct _GList GList;
-
-struct _GList
-{
- gpointer data;
- GList *next;
- GList *prev;
-};
-</verb></tscreen>
-
-A GList structure is just a simple structure for doubly linked lists.
-there exist several g_list_*() functions to modify a linked list in
-glib.h. However the GTK_LIST(MyGtkList)->selection is maintained
-by the gtk_list_*() functions and should not be modified.
-
-The selection_mode of the GtkList determines the selection
-facilities of a GtkList and therefore the contents
-of GTK_LIST(AnyGtkList)->selection:
-
-<verb>
-selection_mode GTK_LIST()->selection contents
-------------------------------------------------------
-
-GTK_SELECTION_SINGLE selection is either NULL
- or contains a GList* pointer
- for a single selected item.
-
-GTK_SELECTION_BROWSE selection is NULL if the list
- contains no widgets, otherwise
- it contains a GList* pointer
- for one GList structure.
-
-GTK_SELECTION_MULTIPLE selection is NULL if no listitems
- are selected or a a GList* pointer
- for the first selected item. that
- in turn points to a GList structure
- for the second selected item and so
- on.
-
-GTK_SELECTION_EXTENDED selection is NULL.
-</verb>
-
-The data field of the GList structure GTK_LIST(MyGtkList)->selection points
-to the first GtkListItem that is selected. So if you would like to determine
-which listitems are selected you should go like this:
-
-Upon Initialization:
-<tscreen><verb>
-{
- gchar *list_items[]={
- "Item0",
- "Item1",
- "foo",
- "last Item",
- };
- guint nlist_items=sizeof(list_items)/sizeof(list_items[0]);
- GtkWidget *list_item;
- guint i;
-
- list=gtk_list_new();
- gtk_list_set_selection_mode(GTK_LIST(list), GTK_SELECTION_MULTIPLE);
- gtk_container_add(GTK_CONTAINER(AnyGtkContainer), list);
- gtk_widget_show (list);
-
- for (i = 0; i < nlist_items; i++)
- {
- list_item=gtk_list_item_new_with_label(list_items[i]);
- gtk_object_set_user_data(GTK_OBJECT(list_item), (gpointer)i);
- gtk_container_add(GTK_CONTAINER(list), list_item);
- gtk_widget_show(list_item);
- }
-}
-</verb></tscreen>
-
-To get known about the selection:
-<tscreen><verb>
-{
- GList *items;
-
- items=GTK_LIST(list)->selection;
-
- printf("Selected Items: ");
- while (items) {
- if (GTK_IS_LIST_ITEM(items->data))
- printf("%d ", (guint)
- gtk_object_get_user_data(items->data));
- items=items->next;
- }
- printf("\n");
-}
-</verb></tscreen>
-
-<!-- ----------------------------------------------------------------- -->
-<sect1>How do I stop the column headings of a GtkCList disappearing
-when the list is scrolled?
-<p>
-This happens when a GtkCList is packed into a GtkScrolledWindow using
-the function <tt/gtk_scroll_window_add_with_viewport()/. The prefered
-method of adding a CList to a scrolled window is to use the function
-<tt/gtk_container_add/, as in:
-
-<tscreen><verb>
- GtkWidget *scrolled, *clist;
- char *titles[] = { "Title1" , "Title2" };
-
- scrolled = gtk_scrolled_window_new(NULL, NULL);
-
- clist = gtk_clist_new_with_titles(2, titles);
- gtk_container_add(GTK_CONTAINER(scrolled), clist);
-</verb></tscreen>
-
-<!-- ----------------------------------------------------------------- --><p>
-<sect1>I don't want the user of my applications to enter text into a GtkCombo. Any idea?
-<p>
-A GtkCombo has an associated entry which can be accessed using the
-following expression:
-
-<tscreen><verb>
- GTK_COMBO(combo_widget)->entry
-</verb></tscreen>
-
-If you don't want the user to be able to modify the content of this
-entry, you can use the gtk_entry_set_editable() function:
-
-<tscreen><verb>
- void gtk_entry_set_editable(GtkEntry *entry,
- gboolean editable);
-</verb></tscreen>
-
-Set the editable parameter to FALSE to disable typing into the entry.
-
-<!-- ----------------------------------------------------------------- -->
-<sect1>How do I catch a combo box change?
-<p>
-The entry which is associated to your GtkCombo send a "changed" signal
-when:
-<itemize>
- <item>some text is typed in
- <item>the selection of the combo box is changed
-</itemize>
-
-To catch any combo box change, simply connect your signal handler with
-
-<tscreen><verb>
- gtk_signal_connect(GTK_COMBO(cb)->entry,
- "changed",
- GTK_SIGNAL_FUNC(my_cb_change_handler),
- NULL);
-</verb></tscreen>
-
-<!-- ----------------------------------------------------------------- -->
-<sect1>How can I define a separation line in a menu?
-<p>
-See the <htmlurl url="http://www.gtk.org/tutorial/"
-name="Tutorial"> for information on how to create menus.
-However, to create a separation line in a menu, just insert an
-empty menu item:
-
-<tscreen><verb>
-menuitem = gtk_menu_item_new();
-gtk_menu_append(GTK_MENU(menu), menuitem);
-gtk_widget_show(menuitem);
-</verb></tscreen>
-
-<!-- ----------------------------------------------------------------- -->
-<sect1>How can I right justify a menu, such as Help?
-<p>
-Depending on if you use the MenuFactory or not, there are two ways to
-proceed. With the MenuFactory, use something like the following:
-
-<tscreen><verb>
-menu_path = gtk_menu_factory_find (factory, "<MyApp>/Help");
-gtk_menu_item_right_justify(menu_path->widget);
-</verb></tscreen>
-
-If you do not use the MenuFactory, you should simply use:
-
-<tscreen><verb>
-gtk_menu_item_right_justify(my_menu_item);
-</verb></tscreen>
-
-<!-- ----------------------------------------------------------------- -->
-<sect1>How do I add some underlined accelerators to menu items?
-<p>
-Damon Chaplin, the technical force behind the Glade project, provided
-the following code sample (this code is an output from Glade). It
-creates a small <tt/File/ menu item with only one child
-(<tt/New/). The F in <tt/File/ and the N in <tt/New/ are underlined,
-and the relevant accelerators are created.
-
-<tscreen><verb>
- menubar1 = gtk_menu_bar_new ();
- gtk_object_set_data (GTK_OBJECT (window1), "menubar1", menubar1);
- gtk_widget_show (menubar1);
- gtk_box_pack_start (GTK_BOX (vbox1), menubar1, FALSE, FALSE, 0);
-
- file1 = gtk_menu_item_new_with_label ("");
- tmp_key = gtk_label_parse_uline (GTK_LABEL (GTK_BIN (file1)->child),
- _("_File"));
- gtk_widget_add_accelerator (file1, "activate_item", accel_group,
- tmp_key, GDK_MOD1_MASK, 0);
- gtk_object_set_data (GTK_OBJECT (window1), "file1", file1);
- gtk_widget_show (file1);
- gtk_container_add (GTK_CONTAINER (menubar1), file1);
-
- file1_menu = gtk_menu_new ();
- file1_menu_accels = gtk_menu_ensure_uline_accel_group (GTK_MENU (file1_menu));
- gtk_object_set_data (GTK_OBJECT (window1), "file1_menu", file1_menu);
- gtk_menu_item_set_submenu (GTK_MENU_ITEM (file1), file1_menu);
-
- new1 = gtk_menu_item_new_with_label ("");
- tmp_key = gtk_label_parse_uline (GTK_LABEL (GTK_BIN (new1)->child),
- _("_New"));
- gtk_widget_add_accelerator (new1, "activate_item", file1_menu_accels,
- tmp_key, 0, 0);
- gtk_object_set_data (GTK_OBJECT (window1), "new1", new1);
- gtk_widget_show (new1);
- gtk_container_add (GTK_CONTAINER (file1_menu), new1);
-</verb></tscreen>
-
-<!-- ----------------------------------------------------------------- -->
-<sect1>How can I retrieve the text from a GtkMenuItem?
-<p>
-You can usually retrieve the label of a specific GtkMenuItem with:
-
-<tscreen><verb>
- if (GTK_BIN (menu_item)->child)
- {
- GtkWidget *child = GTK_BIN (menu_item)->child;
-
- /* do stuff with child */
- if (GTK_IS_LABEL (child))
- {
- gchar *text;
-
- gtk_label_get (GTK_LABEL (child), &text);
- g_print ("menu item text: %s\n", text);
- }
- }
-</verb></tscreen>
-
-To get the active menu item from a GtkOptionMenu you can do:
-<tscreen><verb>
-if (GTK_OPTION_MENU (option_menu)->menu_item)
-{
- GtkWidget *menu_item = GTK_OPTION_MENU (option_menu)->menu_item;
-}
-</verb></tscreen>
-
-But, there's a catch. For this specific case, you can <bf>not</bf> get
-the label widget from <tt/menu_item/ with the above code, because the
-option menu reparents the menu_item's child temporarily to display the
-currently active contents. So to retrive the child of the currently
-active menu_item of an option menu, you'll have to do:
-
-<tscreen><verb>
- if (GTK_BIN (option_menu)->child)
- {
- GtkWidget *child = GTK_BIN (option_menu)->child;
-
- /* do stuff with child */
- }
-</verb></tscreen>
-
-<!-- ----------------------------------------------------------------- -->
-<sect1>How do I right (or otherwise) justify a GtkLabel?
-<p>
-Are you sure you want to <em>justify</em> the labels? The label class
-contains the <tt/gtk_label_set_justify()/ function that is used to
-control the justification of a multi-line label.
-
-What you probably want is to set the <em>alignment</em> of the label,
-ie right align it, center it or left align it. If you want to do this,
-you should use:
-
-<tscreen><verb>
-void gtk_misc_set_alignment (GtkMisc *misc,
- gfloat xalign,
- gfloat yalign);
-</verb></tscreen>
-
-where the <tt/xalign/ and <tt/yalign/ values are floats in [0.00;1.00].
-
-<tscreen><verb>
-GtkWidget *label;
-
-/* horizontal : left align, vertical : top */
-gtk_misc_set_alignment(GTK_MISK(label), 0.0f, 0.0f);
-
-/* horizontal : centered, vertical : centered */
-gtk_misc_set_alignment(GTK_MISK(label), 0.5f, 0.5f);
-
-/* horizontal : right align, vertical : bottom */
-gtk_misc_set_alignment(GTK_MISK(label), 1.0f, 1.0f);
-</verb></tscreen>
-
-<!-- ----------------------------------------------------------------- -->
-<sect1>How do I set the background color of a GtkLabel widget?
-<p>
-The Gtklabel widget is one of a few GTK+ widgets that don't create
-their own window to render themselves into. Instead, they draw
-themselves directly onto their parents window.
-
-This means that in order to set the background color for a GtkLabel
-widget, you need to change the background color of its parent,
-i.e. the object that you pack it into.
-
-<!-- ----------------------------------------------------------------- -->
-<sect1>How do I set the color and font of a GtkLabel using a Resource File?
-<p>
-The widget name path constructed for a Label consists of the widget
-names of its object hierarchy as well, e.g.
-
-<verb>
-window (name: humphrey)
- hbox
- label (name: mylabel)
-</verb>
-
-The widget path your pattern needs to match would be:
-<tt/humphrey.GtkHBox.mylabel/
-
-The resource file may look something like:
-
-<verb>
-style "title"
-{
- fg[NORMAL] = {1.0, 0.0, 0.0}
- font = "-adobe-helvetica-bold-r-normal--*-140-*-*-*-*-*-*"
-}
-widget "*mylabel" style "title"
-</verb>
-
-In your program, you would also need to give a name to the Label
-widget, which can be done using:
-<verb>
- label = gtk_label_new("Some Label Text");
- gtk_widget_set_name(label, "mylabel");
- gtk_widget_show(label);
-</verb>
-
-<!-- ----------------------------------------------------------------- -->
-<sect1>How do I configure Tooltips in a Resource File?
-<p>
-The tooltip's window is named "gtk-tooltips", GtkTooltips in itself is
-not a GtkWidget (though a GtkObject) and as such is not attempted to
-match any widget styles.
-
-So, you resource file should look something like:
-<verb>
-style "postie"
-{
- bg[NORMAL] = {1.0, 1.0, 0.0}
-}
-widget "gtk-tooltips*" style "postie"
-</verb>
-
-<!-- ----------------------------------------------------------------- -->
-<sect1>I can't add more than (something like) 2000 chars in a GtkEntry. What's wrong?
-<p>
-There is now a known problem in the GtkEntry widget. In the
-<tt/gtk_entry_insert_text()/ function, the following lines limit
-the number of chars in the entry to 2047.
-
-<tscreen><verb>
- /* The algorithms here will work as long as, the text size (a
- * multiple of 2), fits into a guint16 but we specify a shorter
- * maximum length so that if the user pastes a very long text, there
- * is not a long hang from the slow X_LOCALE functions. */
-
- if (entry->text_max_length == 0)
- max_length = 2047;
- else
- max_length = MIN (2047, entry->text_max_length);
-</verb></tscreen>
-
-<!-- ----------------------------------------------------------------- -->
-<sect1>How do I make a GtkEntry widget activate on pressing the Return key?
-<p>
-The Entry widget emits an 'activate' signal when you press return in
-it. Just attach to the activate signal on the entry and do whatever you
-want to do. Typical code would be:
-
-<tscreen><verb>
- entry = gtk_entry_new();
- gtk_signal_connect (GTK_OBJECT(entry), "activate",
- GTK_SIGNAL_FUNC(entry_callback),
- NULL);
-</verb></tscreen>
-
-<!-- ----------------------------------------------------------------- -->
-<sect1>How do I validate/limit/filter the input to a GtkEntry?
-<p>
-If you want to validate the text that a user enters into a GtkEntry
-widget you can attach to the "insert_text" signal of the entry, and
-modify the text within the callback function. The example below forces
-all characters to uppercase, and limits the range of characters to
-A-Z. Note that the entry is cast to an object of type GtkEditable,
-from which GtkEntry is derived.
-
-<tscreen><verb>
-#include <ctype.h>
-#include <gtk/gtk.h>
-
-void insert_text_handler (GtkEntry *entry,
- const gchar *text,
- gint length,
- gint *position,
- gpointer data)
-{
- GtkEditable *editable = GTK_EDITABLE(entry);
- int i, count=0;
- gchar *result = g_new (gchar, length);
-
- for (i=0; i < length; i++) {
- if (!isalpha(text[i]))
- continue;
- result[count++] = islower(text[i]) ? toupper(text[i]) : text[i];
- }
-
- if (count > 0) {
- gtk_signal_handler_block_by_func (GTK_OBJECT (editable),
- GTK_SIGNAL_FUNC (insert_text_handler),
- data);
- gtk_editable_insert_text (editable, result, count, position);
- gtk_signal_handler_unblock_by_func (GTK_OBJECT (editable),
- GTK_SIGNAL_FUNC (insert_text_handler),
- data);
- }
- gtk_signal_emit_stop_by_name (GTK_OBJECT (editable), "insert_text");
-
- g_free (result);
-}
-
-int main (int argc,
- char *argv[])
-{
- GtkWidget *window;
- GtkWidget *entry;
-
- gtk_init (&argc, &argv);
-
- /* create a new window */
- window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
- gtk_window_set_title(GTK_WINDOW (window), "GTK Entry");
- gtk_signal_connect(GTK_OBJECT (window), "delete_event",
- (GtkSignalFunc) gtk_exit, NULL);
-
- entry = gtk_entry_new();
- gtk_signal_connect(GTK_OBJECT(entry), "insert_text",
- GTK_SIGNAL_FUNC(insert_text_handler),
- NULL);
- gtk_container_add(GTK_CONTAINER (window), entry);
- gtk_widget_show(entry);
-
- gtk_widget_show(window);
-
- gtk_main();
- return(0);
-}
-</verb></tscreen>
-
-<!-- ----------------------------------------------------------------- -->
-<sect1>How do I use horizontal scrollbars with a GtkText widget?
-<p>
-The short answer is that you can't. The current version of the GtkText
-widget does not support horizontal scrolling. There is an intention to
-completely rewrite the GtkText widget, at which time this limitation
-will be removed.
-
-<!-- ----------------------------------------------------------------- -->
-<sect1>How do I change the font of a GtkText widget?
-<p>
-There are a couple of ways of doing this. As GTK+ allows the
-appearance of applications to be changed at run time using resources
-you can use something like the following in the appropriate
-file:
-
-<tscreen><verb>
-style "text"
-{
- font = "-adobe-helvetica-medium-r-normal--*-100-*-*-*-*-*-*"
-}
-</verb></tscreen>
-
-Another way to do this is to load a font within your program, and then
-use this in the functions for adding text to the text widget. You can
-load a font using, for example:
-
-<tscreen><verb>
- GdkFont *font;
- font = gdk_font_load("-adobe-helvetica-medium-r-normal--*-140-*-*-*-*-*-*");
-</verb></tscreen>
-
-<!-- ----------------------------------------------------------------- -->
-<sect1>How do I set the cursor position in a GtkText object?
-<p>
-Notice that the response is valid for any object that inherits from the
-GtkEditable class.
-
-Are you sure that you want to move the cursor position? Most of the
-time, while the cursor position is good, the insertion point does not
-match the cursor position. If this apply to what you really want, then
-you should use the <tt/gtk_text_set_point()/ function. If you want to
-set the insertion point at the current cursor position, use the
-following:
-
-<tscreen><verb>
- gtk_text_set_point(GTK_TEXT(text),
- gtk_editable_get_position(GTK_EDITABLE(text)));
-</verb></tscreen>
-
-If you want the insertion point to follow the cursor at all time, you
-should probably catch the button press event, and then move the
-insertion point. Be careful : you'll have to catch it after the widget
-has changed the cursor position though. Thomas Mailund Jensen proposed
-the following code:
-
-<tscreen><verb>
-static void
-insert_bar (GtkWidget *text)
-{
- /* jump to cursor mark */
- gtk_text_set_point (GTK_TEXT (text),
- gtk_editable_get_position (GTK_EDITABLE (text)));
-
- gtk_text_insert (GTK_TEXT (text), NULL, NULL, NULL,
- "bar", strlen ("bar"));
-}
-
-int
-main (int argc, char *argv[])
-{
- GtkWidget *window, *text;
-
- gtk_init (&argc, &argv);
-
- window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
- text = gtk_text_new (NULL, NULL);
- gtk_text_set_editable (GTK_TEXT (text), TRUE);
- gtk_container_add (GTK_CONTAINER (window), text);
-
- /* connect after everything else */
- gtk_signal_connect_after (GTK_OBJECT(text), "button_press_event",
- GTK_SIGNAL_FUNC (insert_bar), NULL);
-
- gtk_widget_show_all(window);
- gtk_main();
-
- return 0;
-}
-</verb></tscreen>
-
-Now, if you really want to change the cursor position, you should use the
-<tt/gtk_editable_set_position()/ function.
-
-<!-- ***************************************************************** -->
-<sect>About gdk
-<!-- ***************************************************************** -->
-
-<!-- ----------------------------------------------------------------- -->
-<sect1>What is GDK?
-<p>
-GDK is basically a wrapper around the standard Xlib function calls. If
-you are at all familiar with Xlib, a lot of the functions in GDK will
-require little or no getting used to. All functions are written to
-provide an way to access Xlib functions in an easier and slightly more
-intuitive manner. In addition, since GDK uses GLib (see below), it
-will be more portable and safer to use on multiple platforms.
-
-<!-- Examples, anybody? I've been mulling some over. NF -->
-
-<!-- ----------------------------------------------------------------- -->
-<sect1>How do I use color allocation?
-<p>
-One of the nice things about GDK is that it's based on top of Xlib; this is
-also a problem, especially in the area of color management. If you want
-to use color in your program (drawing a rectangle or such, your code
-should look something like this:
-<tscreen>
-<verb>
-{
- GdkColor *color;
- int width, height;
- GtkWidget *widget;
- GdkGC *gc;
-
- ...
-
- /* first, create a GC to draw on */
- gc = gdk_gc_new(widget->window);
-
- /* find proper dimensions for rectangle */
- gdk_window_get_size(widget->window, &width, &height);
-
- /* the color we want to use */
- color = (GdkColor *)malloc(sizeof(GdkColor));
-
- /* red, green, and blue are passed values, indicating the RGB triple
- * of the color we want to draw. Note that the values of the RGB components
- * within the GdkColor are taken from 0 to 65535, not 0 to 255.
- */
- color->red = red * (65535/255);
- color->green = green * (65535/255);
- color->blue = blue * (65535/255);
-
- /* the pixel value indicates the index in the colormap of the color.
- * it is simply a combination of the RGB values we set earlier
- */
- color->pixel = (gulong)(red*65536 + green*256 + blue);
-
- /* However, the pixel valule is only truly valid on 24-bit (TrueColor)
- * displays. Therefore, this call is required so that GDK and X can
- * give us the closest color available in the colormap
- */
- gdk_color_alloc(gtk_widget_get_colormap(widget), color);
-
- /* set the foreground to our color */
- gdk_gc_set_foreground(gc, color);
-
- /* draw the rectangle */
- gdk_draw_rectangle(widget->window, gc, 1, 0, 0, width, height);
-
- ...
-}
-</verb>
-</tscreen>
-
-<!-- ***************************************************************** -->
-<sect>About GLib
-<!-- ***************************************************************** -->
-
-<!-- ----------------------------------------------------------------- -->
-<sect1>What is GLib?
-<p>
-GLib is a library of useful functions and definitions available for use
-when creating GDK and GTK applications. It provides replacements for some
-standard libc functions, such as malloc, which are buggy on some systems.
-<p>
-It also provides routines for handling:
-<itemize>
-<item>Doubly Linked Lists
-<item>Singly Linked Lists
-<item>Timers
-<item>String Handling
-<item>A Lexical Scanner
-<item>Error Functions
-</itemize>
-
-<!-- ----------------------------------------------------------------- -->
-<sect1>How can I use the doubly linked lists?
-<p>
-The GList object is defined as:
-
-<tscreen><verb>
-typedef struct _GList GList;
-
-struct _GList
-{
- gpointer data;
- GList *next;
- GList *prev;
-};
-</verb></tscreen>
-
-To use the GList objects, simply :
-
-<tscreen><verb>
-GList *list = NULL;
-GList *listrunner;
-gint array[] = { 1, 2, 3, 4, 5, 6 };
-gint pos;
-gint *value;
-
-/* add data to the list */
-for (pos=0;pos < sizeof array; pos++) {
- list = g_list_append(list, (gpointer)&array[pos]);
-}
-
-/* run through the list */
-listrunner = g_list_first(list);
-while (listrunner) {
- value = (gint *)listrunner->data;
- printf("%d\n", *value);
- listrunner = g_list_next(listrunner);
-}
-
-/* removing datas from the list */
-listrunner = g_list_first(list);
-list = g_list_remove_link(list, listrunner);
-list = g_list_remove(list, &array[4]);
-</verb></tscreen>
-
-The same code is usable with singly linked lists (GSList objects) by replacing
-g_list_* functions with the relevant g_slist_* ones (g_slist_append,
-g_slist_remove, ...). Just remember that since you can't go backward in a singly
-linked list, there is no g_slist_first function - you'll need to keep a
-reference on the first node of the list.
-
-<!-- Some Examples might be useful here! NF -->
-<!-- I believe it should be better :) ED -->
-<!-- Linked lists are pretty standard data structures - don't want to
- over do it - TRG -->
-
-<!-- ----------------------------------------------------------------- -->
-<sect1>Memory does not seem to be released when I free the list nodes I've allocated
-<p>
-GLib tries to be "intelligent" on this special issue: it assumes that
-you are likely to reuse the objects, so caches the allocated memory.
-If you do not want to use this behavior, you'll probably want to set
-up a special allocator.
-
-To quote Tim Janik:
-<quote>
-If you have a certain portion of code that uses *lots* of GLists or
-GNodes, and you know you'd better want to release all of them after a
-short while, you'd want to use a GAllocator. Pushing an allocator into
-g_list will make all subsequent glist operations private to that
-allocator's memory pool (and thus you have to take care to pop the
-allocator again, before making any external calls):
-</quote>
-
-<tscreen><verb>
-GAllocator *allocator;
-GList *list = NULL;
-guint i;
-
-/* set a new allocation pool for GList nodes */
-allocator = g_allocator_new ("list heap", 1024);
-g_list_push_allocator (allocator);
-
-/* do some list operations */
-for (i = 0; i < 4096; i++)
- list = g_list_prepend (list, NULL);
-list = g_list_reverse (list);
-
-/* beware to pop allocator befor calling external functions */
-g_list_pop_allocator ();
-gtk_label_set_text (GTK_LABEL (some_label), "some text");
-
-/* and set our private glist pool again */
-g_list_push_allocator (allocator);
-
-/* do some list operations */
-g_list_free (list);
-list = NULL;
-for (i = 0; i < 4096; i++)
- list = g_list_prepend (list, NULL);
-
-/* and back out (while freeing all of the list nodes in our pool) */
-g_list_pop_allocator ();
-g_allocator_free (allocator);
-</verb></tscreen>
-
-<!-- ----------------------------------------------------------------- -->
-<sect1>Why use g_print, g_malloc, g_strdup and fellow glib functions?
-<p>
-Thanks to Tim Janik who wrote to gtk-list: (slightly modified)
-<quote>
-Regarding g_malloc(), g_free() and siblings, these functions are much
-safer than their libc equivalents. For example, g_free() just returns
-if called with NULL. Also, if USE_DMALLOC is defined, the definition
-for these functions changes (in glib.h) to use MALLOC(), FREE() etc...
-If MEM_PROFILE or MEM_CHECK are defined, there are even small
-statistics made counting the used block sizes (shown by
-g_mem_profile() / g_mem_check()).
-<p>
-Considering the fact that glib provides an interface for memory chunks
-to save space if you have lots of blocks that are always the same size
-and to mark them ALLOC_ONLY if needed, it is just straight forward to
-create a small saver (debug able) wrapper around the normal malloc/free
-stuff as well - just like gdk covers Xlib. ;)
-<p>
-Using g_error() and g_warning() inside of applications like the GIMP
-that fully rely on gtk even gives the opportunity to pop up a window
-showing the messages inside of a gtk window with your own handler
-(by using g_set_error_handler()) along the lines of <tt/gtk_print()/
-(inside of gtkmain.c).
-</quote>
-
-<!-- ----------------------------------------------------------------- -->
-<sect1>What's a GScanner and how do I use one?
-<p>
-A GScanner will tokenize your text, that is, it'll return an integer
-for every word or number that appears in its input stream, following
-certain (customizable) rules to perform this translation.
-You still need to write the parsing functions on your own though.
-
-Here's a little test program supplied by Tim Janik that will parse
-
-<verb>
-<SYMBOL> = <OPTIONAL-MINUS> <NUMBER> ;
-</verb>
-
-constructs, while skipping "#\n" and "/**/" style comments.
-
-<verb>
-#include <glib.h>
-
-/* some test text to be fed into the scanner */
-static const gchar *test_text =
-( "ping = 5;\n"
- "/* slide in some \n"
- " * comments, just for the\n"
- " * fun of it \n"
- " */\n"
- "pong = -6; \n"
- "\n"
- "# the next value is a float\n"
- "zonk = 0.7;\n"
- "# redefine ping\n"
- "ping = - 0.5;\n" );
-
-/* define enumeration values to be returned for specific symbols */
-enum {
- SYMBOL_PING = G_TOKEN_LAST + 1,
- SYMBOL_PONG = G_TOKEN_LAST + 2,
- SYMBOL_ZONK = G_TOKEN_LAST + 3
-};
-
-/* symbol array */
-static const struct {
- gchar *symbol_name;
- guint symbol_token;
-} symbols[] = {
- { "ping", SYMBOL_PING, },
- { "pong", SYMBOL_PONG, },
- { "zonk", SYMBOL_ZONK, },
- { NULL, 0, },
-}, *symbol_p = symbols;
-
-static gfloat ping = 0;
-static gfloat pong = 0;
-static gfloat zonk = 0;
-
-static guint
-parse_symbol (GScanner *scanner)
-{
- guint symbol;
- gboolean negate = FALSE;
-
- /* expect a valid symbol */
- g_scanner_get_next_token (scanner);
- symbol = scanner->token;
- if (symbol < SYMBOL_PING ||
- symbol > SYMBOL_ZONK)
- return G_TOKEN_SYMBOL;
-
- /* expect '=' */
- g_scanner_get_next_token (scanner);
- if (scanner->token != '=')
- return '=';
-
- /* feature optional '-' */
- g_scanner_peek_next_token (scanner);
- if (scanner->next_token == '-')
- {
- g_scanner_get_next_token (scanner);
- negate = !negate;
- }
-
- /* expect a float (ints are converted to floats on the fly) */
- g_scanner_get_next_token (scanner);
- if (scanner->token != G_TOKEN_FLOAT)
- return G_TOKEN_FLOAT;
-
- /* make sure the next token is a ';' */
- if (g_scanner_peek_next_token (scanner) != ';')
- {
- /* not so, eat up the non-semicolon and error out */
- g_scanner_get_next_token (scanner);
- return ';';
- }
-
- /* assign value, eat the semicolon and exit successfully */
- switch (symbol)
- {
- case SYMBOL_PING:
- ping = negate ? - scanner->value.v_float : scanner->value.v_float;
- break;
- case SYMBOL_PONG:
- pong = negate ? - scanner->value.v_float : scanner->value.v_float;
- break;
- case SYMBOL_ZONK:
- zonk = negate ? - scanner->value.v_float : scanner->value.v_float;
- break;
- }
- g_scanner_get_next_token (scanner);
-
- return G_TOKEN_NONE;
-}
-
-int
-main (int argc, char *argv[])
-{
- GScanner *scanner;
- guint expected_token;
-
- scanner = g_scanner_new (NULL);
-
- /* adjust lexing behaviour to suit our needs
- */
- /* convert non-floats (octal values, hex values...) to G_TOKEN_INT */
- scanner->config->numbers_2_int = TRUE;
- /* convert G_TOKEN_INT to G_TOKEN_FLOAT */
- scanner->config->int_2_float = TRUE;
- /* don't return G_TOKEN_SYMBOL, but the symbol's value */
- scanner->config->symbol_2_token = TRUE;
-
- /* load symbols into the scanner */
- while (symbol_p->symbol_name)
- {
- g_scanner_add_symbol (scanner,
- symbol_p->symbol_name,
- GINT_TO_POINTER (symbol_p->symbol_token));
- symbol_p++;
- }
-
- /* feed in the text */
- g_scanner_input_text (scanner, test_text, strlen (test_text));
-
- /* give the error handler an idea on how the input is named */
- scanner->input_name = "test text";
-
- /* scanning loop, we parse the input until its end is reached,
- * the scanner encountered a lexing error, or our sub routine came
- * across invalid syntax
- */
- do
- {
- expected_token = parse_symbol (scanner);
-
- g_scanner_peek_next_token (scanner);
- }
- while (expected_token == G_TOKEN_NONE &&
- scanner->next_token != G_TOKEN_EOF &&
- scanner->next_token != G_TOKEN_ERROR);
-
- /* give an error message upon syntax errors */
- if (expected_token != G_TOKEN_NONE)
- g_scanner_unexp_token (scanner, expected_token, NULL, "symbol", NULL, NULL, TRUE);
-
- /* finsish parsing */
- g_scanner_destroy (scanner);
-
- /* print results */
- g_print ("ping: %f\n", ping);
- g_print ("pong: %f\n", pong);
- g_print ("zonk: %f\n", zonk);
-
- return 0;
-}
-</verb>
-
-You need to understand that the scanner will parse its input and
-tokenize it, it is up to you to interpret these tokens, not define
-their types before they get parsed, e.g. watch gscanner parse a
-string:
-
-<verb>
-"hi i am 17"
- | | | |
- | | | v
- | | v TOKEN_INT, value: 17
- | v TOKEN_IDENTIFIER, value: "am"
- v TOKEN_CHAR, value: 'i'
-TOKEN_IDENTIFIER, value: "hi"
-</verb>
-
-If you configure the scanner with:
-<verb>
-scanner->config->int_2_float = TRUE;
-scanner->config->char_2_token = TRUE;
-scanner->config->scan_symbols = TRUE;
-</verb>
-
-and add "am" as a symbol with
-<verb>
-g_scanner_add_symbol (scanner, "am", "symbol value");
-</verb>
-
-GScanner will parse it as
-
-<verb>
-"hi i am 17"
- | | | |
- | | | v
- | | v TOKEN_FLOAT, value: 17.0 (automatic int->float conversion)
- | | TOKEN_SYMBOL, value: "symbol value" (a successfull hash table lookup
- | | turned a TOKEN_IDENTIFIER into a
- | | TOKEN_SYMBOL and took over the
- | v symbol's value)
- v 'i' ('i' can be a valid token as well, as all chars >0 and <256)
-TOKEN_IDENTIFIER, value: "hi"
-</verb>
-
-You need to match the token sequence with your code, and if you encounter
-something that you don't want, you error out:
-
-<verb>
-/* expect an identifier ("hi") */
-g_scanner_get_next_token (scanner);
-if (scanner->token != G_TOKEN_IDENTIFIER)
- return G_TOKEN_IDENTIFIER;
-/* expect a token 'i' */
-g_scanner_get_next_token (scanner);
-if (scanner->token != 'i')
- return 'i';
-/* expect a symbol ("am") */
-g_scanner_get_next_token (scanner);
-if (scanner->token != G_TOKEN_SYMBOL)
- return G_TOKEN_SYMBOL;
-/* expect a float (17.0) */
-g_scanner_get_next_token (scanner);
-if (scanner->token != G_TOKEN_FLOAT)
- return G_TOKEN_FLOAT;
-</verb>
-
-If you got past here, you have parsed "hi i am 17" and would have
-accepted "dooh i am 42" and "bah i am 0.75" as well, but you would
-have not accepted "hi 7 am 17" or "hi i hi 17".
-
-<!-- ***************************************************************** -->
-<sect>GTK+ FAQ Contributions, Maintainers and Copyright
-<p>
-If you would like to make a contribution to the FAQ, send either one
-of us an e-mail message with the exact text you think should be
-included (question and answer). With your help, this document can grow
-and become more useful!
-
-This document is maintained by
-Tony Gale <htmlurl url="mailto:gale@gtk.org"
-name="<gale@gtk.org>">
-Nathan Froyd <htmlurl url="mailto:maestrox@geocities.com"
-name="<maestrox@geocities.com>">,
-and
-Emmanuel Deloget <htmlurl url="mailto:logout@free.fr"
-name="<logout@free.fr>">.
-This FAQ was created by Shawn T. Amundson
-<htmlurl url="mailto:amundson@gimp.org"
-name="<amundson@gimp.org>"> who continues to provide support.
-
-Contributions should be sent to Tony Gale <htmlurl
-url="mailto:gale@gtk.org" name="<gale@gtk.org>">
-
-The GTK+ FAQ is Copyright (C) 1997-2000 by Shawn T. Amundson,
-Tony Gale, Emmanuel Deloget and Nathan Froyd.
-
-Permission is granted to make and distribute verbatim copies of this
-manual provided the copyright notice and this permission notice are
-preserved on all copies.
-
-Permission is granted to copy and distribute modified versions of this
-document under the conditions for verbatim copying, provided that this
-copyright notice is included exactly as in the original, and that the
-entire resulting derived work is distributed under the terms of a
-permission notice identical to this one.
-
-Permission is granted to copy and distribute translations of this
-document into another language, under the above conditions for
-modified versions.
-
-If you are intending to incorporate this document into a published
-work, please contact one of the maintainers, and we will make an
-effort to ensure that you have the most up to date information
-available.
-
-There is no guarentee that this document lives up to its intended
-purpose. This is simply provided as a free resource. As such, the
-authors and maintainers of the information provided within can not
-make any guarentee that the information is even accurate.
-
-</article>